camerauis/cameraapp/generic/src/CamImageSaveActive.cpp
branchRCL_3
changeset 24 bac7acad7cb3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/camerauis/cameraapp/generic/src/CamImageSaveActive.cpp	Wed Sep 01 12:30:54 2010 +0100
@@ -0,0 +1,1148 @@
+/*
+* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Active object that manages saving and deletion of images*
+*/
+
+
+
+// INCLUDE FILES
+#include <badesca.h>
+#include <eikenv.h>
+#include <sysutil.h>
+#include <AknProgressDialog.h>
+#include <eikprogi.h>
+#include <StringLoader.h>
+#include <AknQueryDialog.h>
+#include <pathinfo.h>
+
+// includes to allow reporting to LifeBlog via publish and subscribe API
+#include <e32property.h>
+
+#include <cameraapp.rsg>
+#include <vgacamsettings.rsg>
+
+#include "CamImageSaveActive.h"
+#include "CamPanic.h"
+#include "CamUtility.h"
+#include "CamPerformance.h"
+#include "cambuffershare.h"
+#include "OstTraceDefinitions.h"
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include "CamImageSaveActiveTraces.h"
+#endif
+#include "camuidconstants.h" // KPSUidCamcorderNotifier
+
+#include "CameraappPrivateCRKeys.h"
+
+#include "CamAppController.h"
+#include "CameraUiConfigManager.h"
+#include "CamBurstCaptureArray.h"
+
+const TUint32 KCamLatestFilePath      = 0x00000001;
+const TInt    KArrayGranularity       = 2;
+const TInt    KCapturedAlbumId        = 2; 
+
+// CONSTANTS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CCamImageSaveActive* CCamImageSaveActive::NewL( MCamImageSaveObserver& aObserver,  
+                                                CCamAppController&  aController )
+    {
+    PRINT( _L("Camera => CCamImageSaveActive::NewL") );
+
+    CCamImageSaveActive* self = new( ELeave ) CCamImageSaveActive( aObserver, 
+                                                                   aController );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    PRINT( _L("Camera <= CCamImageSaveActive::NewL") );
+    return self;
+    }
+
+    
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::~CCamImageSaveActive
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CCamImageSaveActive::~CCamImageSaveActive()
+    {
+    PRINT( _L("Camera => ~CCamImageSaveActive") );
+    delete iSaveArray;
+
+    delete iNameArray;
+    iSnapArray.ResetAndDestroy();
+    delete iManager;
+            
+    ReleaseAllAndDestroy( iImageArray );
+    iImageArray.Close();
+
+    iThumbnailRequests.Close();
+    DoDismissProgressNote();
+
+#if defined(RD_MDS_2_5) && !defined(__WINSCW__) && !defined(__WINS__)
+    DeRegisterHarverterClientEvents();
+#endif // defined(RD_MDS_2_5) && !defined(__WINSCW__) && !defined(__WINS__)
+
+    PRINT( _L("Camera <= ~CCamImageSaveActive") );
+    }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::Cancel
+// Cancel any current or pending actions
+// -----------------------------------------------------------------------------
+//
+void CCamImageSaveActive::Cancel()
+    {
+    PRINT( _L( "Camera => CCamImageSaveActive::Cancel" ) );
+ 
+    TBool storageOk( ETrue );
+    if ( iController.SequenceCaptureInProgress() )
+        {
+        TCamMediaStorage storageLocation = static_cast<TCamMediaStorage> ( 
+                iController.IntegerSettingValueUnfiltered(  
+                        ECamSettingItemPhotoMediaStorage ) );
+        if ( storageLocation == ECamMediaStorageCard )
+            {
+            // Avoid deleting and saving to drive which does not exist
+            storageOk = CamUtility::MemoryCardStatus() == ECamMemoryCardInserted;
+            PRINT1( _L( "Camera => CCamImageSaveActive::Cancel storageOk=%d" ), storageOk);
+            }
+        }
+
+    // Since this function may be called in the destructor, we need to check
+    // that iSaveArray is not null. 
+    if(iSaveArray)
+        {
+        TInt count = iSaveArray->Count() - 1;
+        TInt lowest = 0;
+        if ( iSaveCurrent )
+            {
+            lowest = 1;
+            }
+        TInt i;
+
+        // Delete all dummy files except any currently saving one
+        for ( i = count; i >= lowest; i-- )
+            {
+            PRINT1( _L( "Camera Deleting file index %d" ), i );         
+            if( storageOk )
+                {
+                DeleteFile( iSaveArray->MdcaPoint( i ), ETrue );  
+                }
+            }
+        }
+    // if a file is currently saving, delay cleanup till save completes
+    // if ( iSaveCurrent )
+    if ( IsActive() && storageOk )
+        {
+        PRINT( _L( "Camera File currently saving delay cleanup" ) );         
+        iDoCancel = ETrue;
+        if ( !iWait.IsStarted() )
+          {
+          iWait.Start();
+          }
+        }
+    // otherwise, complete cleanup now
+    else
+        {
+        PRINT( _L( "Camera No file saving cleanup now" ) );         
+        DoDismissProgressNote();
+        CActive::Cancel();
+        if(iSaveArray)
+            {
+            iSaveArray->Reset();
+            }
+        ReleaseAllAndDestroy( iImageArray );
+        }
+    PRINT( _L( "Camera <= CCamImageSaveActive::Cancel" ) );         
+    }
+
+void CCamImageSaveActive::ForceCancel()
+{
+    CActive::Cancel();
+}
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::AddToSave
+// Add an image to the list of required saves, activate if needed
+// -----------------------------------------------------------------------------
+//
+TBool CCamImageSaveActive::AddToSave( const TDesC&     aFilename, 
+                                      CCamBufferShare* aImageData )
+    {
+    PRINT( _L("Camera => CCamImageSaveActive::AddToSave") );
+    if( aImageData )
+      {
+      aImageData->Reserve();
+      }
+
+    // Keep note of how many items exist before we try to add a new one
+    TInt count = iSaveArray->Count();
+    TRAPD( err, iSaveArray->AppendL( aFilename ) );
+    if ( !err )
+        {
+        TRAP( err, iImageArray.AppendL( aImageData ) );
+        }
+    // if any of the appends failed then clean out the partial item
+    if ( err )
+        {
+        if ( iSaveArray->Count() > count )
+            {
+            iSaveArray->Delete( count );
+            }
+        if ( iImageArray.Count() > count )
+            {
+            iImageArray.Remove( count );
+            if( aImageData )
+              {
+              aImageData->Release();
+              }
+            }
+        PRINT( _L("Camera <= CCamImageSaveActive::AddToSave, error!") );
+        return EFalse;
+        }
+    // the item is successfully added, start the save now if not currently saving
+    if ( !IsActive() )
+        {
+        SetActiveAndCompleteRequest();
+        }
+
+    PRINT( _L("Camera <= CCamImageSaveActive::AddToSave, ok") );
+    return ETrue;
+    }
+ 
+ 
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::FileSize
+// Returns the size of the data for the specified file
+// -----------------------------------------------------------------------------
+//    
+TInt CCamImageSaveActive::FileSize( const TDesC& aFilename ) const
+    {    
+    TInt size = KErrNotFound;
+    TInt count = iSaveArray->Count();
+    TInt i;
+    
+    // Check to see if it is in the "to be saved" array
+    for ( i = 0; i < count ; i++ )
+        {
+        TPtrC ptr = (*iSaveArray)[i];
+        if ( aFilename.Compare( ptr ) == 0 )    
+            {
+            TRAP_IGNORE( size = iImageArray[i]->SharedBuffer()->DataL( 0 )->Size() );
+            // size = iImageArray[i]->Size();
+            return size;
+            }
+        }   
+        
+    // If we have got here, the requested file is NOT in the array
+    // Check the file system to see if we have already saved it.
+    RFs& fs = CEikonEnv::Static()->FsSession();
+    RFile file;
+    TInt ret = file.Open( fs, aFilename, EFileShareAny | EFileRead );    
+    if ( ret == KErrNone )
+        {
+        file.Size( size );                
+        }
+    file.Close();        
+    return size;
+    }
+    
+    
+    
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::DeleteFile
+// Delete a file, cancelling any pending save
+// -----------------------------------------------------------------------------
+//
+TInt CCamImageSaveActive::DeleteFile( const TDesC& aFilename, 
+                                      TBool aSaveRequested )
+    {
+    RFs& fs = CEikonEnv::Static()->FsSession();
+    if ( aSaveRequested )
+        {
+        TInt index;
+        if ( iSaveArray->Find( aFilename, index ) == 0 )
+            {
+            // if the file is currently being saved
+            if ( index == 0 && iSaveCurrent )
+                {
+                iDeleteCurrent = ETrue;
+                return ETrue;
+                }
+            else
+                {
+                iSaveArray->Delete( index );
+                iSaveArray->Compress();
+
+                CCamBufferShare* item = iImageArray[index];
+                iImageArray.Remove( index );
+                if( item )
+                  {
+                  item->Release();
+                  item = NULL;
+                  }
+
+                iImageArray.Compress();
+                }
+            } 
+        }
+
+    // Dummy files are read only for protection, make sure the file is writable
+    fs.SetAtt( aFilename, 0, KEntryAttReadOnly );
+    TInt ret = fs.Delete( aFilename );  
+    ReportToObserver( ECamSaveEventDeleted );
+
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// CCamImageSaveActive::AlreadySavedFile
+// Returns whether a particular file has already been saved.
+// ---------------------------------------------------------------------------
+//
+TBool CCamImageSaveActive::AlreadySavedFile( const TDesC& aFilename ) const
+    {
+    TInt index;
+    return iSaveArray->Find( aFilename, index );
+    }
+
+// ---------------------------------------------------------------------------
+// CCamImageSaveActive::CurrentlySavingFile
+// Returns whether a particular file is in the process of being saved.
+// ---------------------------------------------------------------------------
+//
+TBool CCamImageSaveActive::CurrentlySavingFile( const TDesC& aFilename ) const
+    {
+    TInt index;
+    if ( iSaveCurrent && ( iSaveArray->Find( aFilename, index ) == 0 ) &&
+        ( index == 0 ) )
+        {
+        return ETrue;
+        }
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::DisplayProgressNote
+// Display the saving progress note until cancelled or completed
+// -----------------------------------------------------------------------------
+//
+void CCamImageSaveActive::DisplayProgressNote( TInt aExpectedImages )
+    {
+    __ASSERT_DEBUG( !iDismissNote, CamPanic( ECamPanicInvalidState ) );
+    // Initialise for a new burst set
+    iSaveProgressCount = 0;
+    iExpectedImages = aExpectedImages;
+    iShowNote = ETrue;
+    if ( !IsActive() )
+        {
+        SetActiveAndCompleteRequest();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::DismissProgressNote
+// Dismiss the saving progress note when completed
+// -----------------------------------------------------------------------------
+//
+void CCamImageSaveActive::DismissProgressNote()
+    {
+    // if the progress note is still pending
+    if ( iShowNote )
+        {
+        // the burst has completed already
+        iShowNote = EFalse;
+        ReportToObserver( ECamSaveEventBurstComplete );
+        }
+
+    // No saves are pending, dismiss the note now
+    if ( !IsActive() )
+        {
+        DoDismissProgressNote();
+        }
+    else // otherwise, wait till all the saves complete
+        {
+        iDismissNote = ETrue;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::SetAddImageToAlbum
+// Set the "Add to album" feature on or off for photos
+// -----------------------------------------------------------------------------
+//
+void CCamImageSaveActive::SetAddImageToAlbum( const TBool aAdding, 
+                                              const TUint32 aDefaultAlbumId )
+    {
+    iAddImageToAlbum = aAdding;
+    iDefaultAlbumId = aDefaultAlbumId;
+    }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::AddToAlbum
+// Add the specified photo or video to the default capture album
+// -----------------------------------------------------------------------------
+//
+#if defined(RD_MDS_2_5) && !defined(__WINSCW__) && !defined(__WINS__)
+void CCamImageSaveActive::AddToAlbum( const TDesC& aFilename,
+                                      const TBool aAddToAlbum,
+                                      const TUint32 aDefaultAlbumId )
+    {
+    OstTrace0( CAMERAAPP_PERFORMANCE_DETAIL, CCAMIMAGESAVEACTIVE_ADDTOALBUM, "e_CCamImageSaveActive_AddToAlbum 1" );
+    PRINT( _L("Camera => CCamImageSaveActive::AddToAlbum") );
+
+    TInt err = KErrNone;
+    RArray<TUint32> harvestAlbumIds;
+    TUint32 harvestAlbumId;
+    err = harvestAlbumIds.Append( KCapturedAlbumId ); 
+
+    /*
+    * NOTE: The default value of album Id defined as per CenRep key is 0, so 
+    *       we add the any other album other than the default one as above
+    *       Secondly, if there is no album set as default album from the 
+    *       precapture settings views then we pass empty array to the harvester
+    *       and MDS harvests the file to camera album directly i.e. captured.
+    */
+
+    if ( aAddToAlbum && aDefaultAlbumId > 0 )
+       {
+       harvestAlbumId = aDefaultAlbumId;
+       err = harvestAlbumIds.Append( harvestAlbumId );
+       }
+    
+    if ( !iHarvesterClientConnected )
+        {
+        PRINT( _L("Camera <> calling iHarvesterClient.Connect") );
+        err = iHarvesterClient.Connect();
+        if ( !err )
+            {
+            iHarvesterClientConnected = ETrue;
+            }
+        PRINT1( _L("Camera <> iHarvesterClient.Connect returned %d"), err );
+        }
+    
+    if ( KErrNone == err )
+        {
+        RegisterForHarvesterEvents();
+
+        PRINT( _L("Camera <> calling iHarvesterClient.HarvestFile") );
+
+#ifdef RD_MDS_2_5   
+        if ( iController.UiConfigManagerPtr() && iController.UiConfigManagerPtr()->IsLocationSupported() )
+            {
+            TBool location = iController.IntegerSettingValue( ECamSettingItemRecLocation );
+			//Never save location information in second camera
+            iHarvesterClient.HarvestFile( aFilename,
+                                          harvestAlbumIds,
+                                          location );
+            }
+        else
+            {
+            iHarvesterClient.HarvestFile( aFilename,
+                                          harvestAlbumIds,
+                                          EFalse );
+            }
+#else // RD_MDS_2_5
+        iHarvesterClient.HarvestFile( aFilename,
+                                      harvestAlbumIds );
+#endif // RD_MDS_2_5
+        
+        PRINT( _L("Camera <> iHarvesterClient.HarvestFile returned") );
+        }
+    harvestAlbumIds.Close();
+
+    PRINT( _L("Camera <= CCamImageSaveActive::AddToAlbum") );
+    OstTrace0( CAMERAAPP_PERFORMANCE_DETAIL, DUP1_CCAMIMAGESAVEACTIVE_ADDTOALBUM, "e_CCamImageSaveActive_AddToAlbum 0" );
+    }
+#else // defined(RD_MDS_2_5) && !defined(__WINSCW__) && !defined(__WINS__)
+void CCamImageSaveActive::AddToAlbum( const TDesC&  /*aFilename*/,
+                                      const TBool   /*aAddToAlbum*/,
+                                      const TUint32 /*aDefaultAlbumId*/ )
+    {
+    }
+#endif // defined(RD_MDS_2_5) && !defined(__WINSCW__) && !defined(__WINS__)
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::Count
+// The number of items in the saving array
+// -----------------------------------------------------------------------------
+//
+TInt CCamImageSaveActive::Count() const
+    {
+    return iSaveArray->Count();
+    }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::CCamImageSaveActive
+// C++ constructor
+// -----------------------------------------------------------------------------
+//
+CCamImageSaveActive::CCamImageSaveActive( MCamImageSaveObserver& aObserver,         
+                                          CCamAppController&  aController )
+    : CActive( EPriorityStandard ), iObserver( aObserver ), 
+    iController( aController ),
+    iFlushing( EFalse )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::ConstructL
+// 2nd phase construction
+// -----------------------------------------------------------------------------
+//
+void CCamImageSaveActive::ConstructL()
+    {
+    PRINT( _L("Camera => CCamImageSaveActive::ConstructL") );
+
+    iSaveArray = new( ELeave ) CDesCArraySeg( KArrayGranularity );
+    iNameArray = new( ELeave ) CDesCArraySeg( KArrayGranularity );
+    CActiveScheduler::Add( this );
+
+    PRINT( _L("Camera <= CCamImageSaveActive::ConstructL") );
+    }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::SetActiveAndCompleteRequest
+// Schedule to run immediately
+// -----------------------------------------------------------------------------
+//
+void CCamImageSaveActive::SetActiveAndCompleteRequest()
+    {
+    SetActive();
+    TRequestStatus* statusPtr = &iStatus;
+    User::RequestComplete( statusPtr, KErrNone );
+    }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::DoCancel
+// Cancels the active object
+// -----------------------------------------------------------------------------
+//
+void CCamImageSaveActive::DoCancel()
+    {
+    PRINT( _L( "Camera => CCamImageSaveActive::DoCancel" ) );      
+    iDismissNote = ETrue;
+    if ( iWait.IsStarted() )
+        {
+        iWait.AsyncStop(); 
+        }
+    iDoCancel = EFalse;
+    // if no new saves have been requested since the cancellation
+    if ( iSaveArray->Count() == 0 )
+        {
+        CActive::Cancel();
+        iSaveArray->Reset();
+
+        ReleaseAllAndDestroy( iImageArray );
+        }
+    PRINT( _L( "Camera <= CCamImageSaveActive::DoCancel" ) );                
+    }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::RunL
+// Clean up after any previous save, then run the next pending save
+// -----------------------------------------------------------------------------
+//
+void CCamImageSaveActive::RunL()
+    {
+    PRINT( _L( "Camera => CCamImageSaveActive::RunL" ) ); 
+    
+    if( !iFlushing )
+        {
+        // if the progress note has been requested
+        if ( iShowNote )
+            {
+            iShowNote = EFalse;
+            DoDisplayProgressNoteL();
+            }
+        // if a save has just completed
+        if ( iSaveCurrent )
+            {
+            CompleteSaveOperation( ETrue );
+            //ReportToObserver( ECamSaveEventComplete );
+            }
+        else
+            {
+            // If cancellation has been requested
+            if ( iDoCancel )
+                {
+                DoCancel();       
+                }
+            }
+        }
+    else
+        {
+        iFlushing = EFalse;
+        CompleteSaveOperation( EFalse );
+        ReportToObserver( ECamSaveEventComplete );
+        }
+    
+    if ( !iSaveCurrent )
+        {
+        // if there are more images to save
+        if ( iSaveArray->Count() > 0 )
+            {
+            DoSaveL();
+            }
+        // if all saves are complete and the progress note needs to be dismissed
+        else if ( iDismissNote )
+            {
+            DoDismissProgressNote();
+            }
+        else if ( iNameArray->Count() > 0 )
+            {
+            DoCreateThumbnailL();
+            }    
+        else // Do nothing
+            {
+            }
+        }
+    PRINT( _L( "Camera <= CCamImageSaveActive::RunL" ) ); 
+    }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::RunError
+//
+// -----------------------------------------------------------------------------
+//
+TInt
+CCamImageSaveActive::RunError( TInt aError )
+  {
+  PRINT1( _L( "Camera => CCamImageSaveActive::RunError, error(%d)"), aError ); 
+  Cancel();
+
+  if( aError == KErrDiskFull || aError == KErrNotReady )
+    {
+    if( aError == KErrNotReady  )
+      {
+      iController.SetCaptureStoppedForUsb( ETrue );
+      }
+    
+    ReportToObserver( ECamSaveEventSaveError );  
+    }
+  else
+    {
+    ReportToObserver( ECamSaveEventCriticalError );  
+    }
+
+  PRINT ( _L( "Camera <= CCamImageSaveActive::RunError") );
+  return KErrNone;
+  }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::CompleteSaveOperation
+// Clean up after the previous save
+// -----------------------------------------------------------------------------
+//
+void CCamImageSaveActive::CompleteSaveOperation( TBool aDoFlush )
+    {
+    OstTrace0( CAMERAAPP_PERFORMANCE_DETAIL, DUP1_CCAMIMAGESAVEACTIVE_COMPLETESAVEOPERATION, "e_CCamImageSaveActive_CompleteSaveOperation 1" );
+    PRINT( _L( "Camera => CCamImageSaveActive::CompleteSaveOperation" ) );     
+    if( aDoFlush )
+        {
+        iFile.Flush(iStatus);
+        iFlushing = ETrue;
+        SetActive();
+        }
+    else
+        {
+        iSaveProgressCount++;
+        // if the saving progress note is open
+        if ( iSaveProgressDialog && iSaveProgressInfo )
+            {
+            // Reset inactivity timer.  Need to call this periodically 
+            // to keep the backlight on
+            User::ResetInactivityTime();
+            // Increment the progress in the progress bar
+            iSaveProgressInfo->IncrementAndDraw( 1 );
+            }
+        iSaveCurrent = EFalse;
+        iFile.Close();
+        // If there is an error or a pending request for deletion
+        if ( iDeleteCurrent || iStatus != KErrNone )
+            {
+            RFs fs = CEikonEnv::Static()->FsSession();
+            fs.Delete( iSaveArray->MdcaPoint( 0 ) );
+            ReportToObserver( ECamSaveEventDeleted );
+            }
+        else // the save is successful, add to album if required
+            {
+            PERF_EVENT_END_L2( EPerfEventSaveImage );         
+    
+            AddToAlbum( iSaveArray->MdcaPoint( 0 ), 
+                        iAddImageToAlbum, 
+                        iDefaultAlbumId );
+    
+            // report to LifeBlog
+            RProperty::Set( KPSUidCamcorderNotifier, KCamLatestFilePath, iSaveArray->MdcaPoint( 0 ) ); 
+            }
+    
+        iDeleteCurrent = EFalse;
+        
+        // Delete the item from the saving arrays
+        iSaveArray->Delete( 0 );
+        iSaveArray->Compress();
+    
+        CCamBufferShare* share = iImageArray[0];
+        iImageArray.Remove( 0 );
+        if( share )
+          {
+          share->Release();
+          share = NULL;
+          }
+        iImageArray.Compress();
+    
+        // If cancellation has been requested
+        if ( iDoCancel )
+            {
+            DoCancel();       
+            }
+        OstTrace0( CAMERAAPP_PERFORMANCE, CCAMIMAGESAVEACTIVE_COMPLETESAVEOPERATION, "e_CAM_APP_SAVE 0" ); 
+        }
+    PRINT1( _L("Camera <> CCamImageSaveActive .. After this file saving, total shared buffers in use: %d"), CCamBufferShare::TotalBufferShareCount() );
+    PRINT( _L( "Camera <= CCamImageSaveActive::CompleteSaveOperation" ) );         
+    OstTrace0( CAMERAAPP_PERFORMANCE_DETAIL, DUP2_CCAMIMAGESAVEACTIVE_COMPLETESAVEOPERATION, "e_CCamImageSaveActive_CompleteSaveOperation 0" );
+    }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::DoSaveL
+// Start a saving operation
+// -----------------------------------------------------------------------------
+//
+void 
+CCamImageSaveActive::DoSaveL()
+  {
+  PERF_EVENT_START_L2( EPerfEventSaveImage );    
+  PRINT( _L( "Camera => CCamImageSaveActive::DoSaveL" ) );     
+  OstTrace0( CAMERAAPP_PERFORMANCE, CCAMIMAGESAVEACTIVE_DOSAVEL, "e_CAM_APP_SAVE 1" );  //CCORAPP_SAVE_START
+  
+  TPtrC filename = iSaveArray->MdcaPoint( 0 );
+
+  PRINT1( _L( "Camera <> CCamImageSaveActive: trying to save file:[%S]"), &filename );
+  if( filename.Length() == 0 )
+      {
+      PRINT( _L( "Camera <= CCamImageSaveActive: DoSaveL Leaving...not a valid filename") );
+      User::Leave( KErrNotReady );
+      }
+
+  // Check disk space
+  TInt drive = 0;
+  __ASSERT_ALWAYS( !RFs::CharToDrive( filename[0], drive ),
+      CamPanic( ECamPanicFileSystemError ) );
+
+  RFs& fs = CEikonEnv::Static()->FsSession();
+
+  TDesC8* data    = iImageArray[0]->SharedBuffer()->DataL( 0 );
+  TBool   noSpace = SysUtil::DiskSpaceBelowCriticalLevelL( &fs, 
+                                                           data->Length(), 
+                                                           drive );
+  if( noSpace )
+    {
+    Cancel();
+    PRINT( _L( "Camera <> CCamImageSaveActive::DoSaveL .. [WARNING] Disk space below critical, LEAVE!" ) );     
+    User::Leave( KErrDiskFull );
+    }
+
+  // The dummy file is read only for protection, make it writable now
+  // Also unhide it so that media gallery can detect it
+  fs.SetAtt( filename, 0, KEntryAttReadOnly|KEntryAttHidden );
+
+  // Open the file
+  TInt err = iFile.Open( fs, filename, EFileWrite );
+
+  // if the file does not exist, create a new one
+  if ( err == KErrNotFound )
+      {
+      User::LeaveIfError( iFile.Create( fs, filename, EFileWrite ) );
+      }
+  // if there was any other problem then leave
+  else if ( err != KErrNone )
+      {
+      User::Leave( err );
+      }
+  // the file exists
+  else
+      {
+      // Make sure the file is at the start
+      TInt seek = 0;
+      User::LeaveIfError( iFile.Seek( ESeekStart, seek ) );
+      }
+
+  if( iController.CurrentMode() == ECamControllerVideo )
+      {
+      // set size 
+      User::LeaveIfError( iFile.SetSize( data->Size() ) );
+      }
+  // Write the image data to file
+  PRINT( _L( "Camera call iFile.Write" ) );     
+  iFile.Write( *(data), iStatus );
+  iSaveCurrent = ETrue;
+  SetActive();
+  PRINT( _L( "Camera <= CCamImageSaveActive::DoSaveL" ) );     
+  }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::DoDisplayProgressNoteL
+// Display the saving progress note
+// -----------------------------------------------------------------------------
+//
+void CCamImageSaveActive::DoDisplayProgressNoteL()
+    {
+    PRINT( _L("Camera => CCamImageSaveActive::DoDisplayProgressNoteL") )
+    __ASSERT_DEBUG( iSaveProgressDialog == NULL , CamPanic( ECamPanicUi ) );
+    TBool reportOnExit = ETrue;
+    // if there are images left to save in this burst set
+    if ( iExpectedImages > iSaveProgressCount )
+        {
+        iSaveProgressDialog = new( ELeave ) CAknProgressDialog( 
+            reinterpret_cast<CEikDialog**>( &iSaveProgressDialog ), ETrue );
+        iSaveProgressDialog->PrepareLC( R_CAM_SAVING_IMAGES_PROGRESS_NOTE );
+        iSaveProgressInfo = iSaveProgressDialog->GetProgressInfoL();
+        iSaveProgressInfo->SetFinalValue( iExpectedImages );
+        TInt i;
+        for ( i = 0; i < iSaveProgressCount; i++ )
+            {
+            // Increment the progress in the bar for previous saves
+            iSaveProgressInfo->IncrementAndDraw( 1 );
+            }
+        // display the dialog and wait until it is dismissed
+        TInt exit = iSaveProgressDialog->RunLD();
+        // the dialog has exited and deleted itself
+        iSaveProgressDialog = NULL;
+        iSaveProgressInfo = NULL;
+        // if the dialog was cancelled by the user
+        if ( exit == 0 )
+            {
+            reportOnExit = EFalse;
+            iCompletedBurst = ETrue;                
+            }
+        }
+    // if the burst has now completed
+    if ( reportOnExit )
+        {
+        ReportToObserver( ECamSaveEventBurstComplete );            
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::DoDismissProgressNote
+// Dismiss the progress note, if it is still open
+// -----------------------------------------------------------------------------
+//
+void CCamImageSaveActive::DoDismissProgressNote()
+    {
+    iDismissNote = EFalse;
+    if ( iSaveProgressDialog )
+        {
+        // Delete the dialog and end its RunLD()
+        TRAPD( error, iSaveProgressDialog->ProcessFinishedL() ) 
+        if (error != KErrNone)
+            {
+            delete iSaveProgressDialog;
+            iSaveProgressDialog = NULL;
+            iSaveProgressInfo = NULL;
+            }
+        }
+    // if the progress note is still pending
+    if ( iShowNote )
+        {
+        // report that the burst has completed
+        iShowNote = EFalse;
+        ReportToObserver( ECamSaveEventBurstComplete );                   
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::ReportToObserver
+// Indicate to the observer that saving has finished
+// -----------------------------------------------------------------------------
+//
+void CCamImageSaveActive::ReportToObserver( TCamSaveEvent aEvent )
+    {
+    if ( aEvent == ECamSaveEventComplete && iCompletedBurst )
+        {
+        aEvent = ECamSaveEventBurstComplete;
+        iCompletedBurst = EFalse;
+        }    
+    iObserver.HandleSaveEvent( aEvent );    
+    }
+
+
+// -----------------------------------------------------------------------------
+// ReleaseAllAndDestroy
+//
+// -----------------------------------------------------------------------------
+//
+void 
+CCamImageSaveActive::ReleaseAllAndDestroy( RPointerArray<CCamBufferShare>& aArray )
+  {
+  PRINT( _L("Camera => CCamImageSaveActive::ReleaseAllAndDestroy") );
+
+  for( TInt i = aArray.Count()-1; i >= 0; i-- )
+    {
+    CCamBufferShare* share = aArray[i];
+    aArray.Remove( i );
+    if( share )
+      {
+      share->Release();
+      share = NULL;
+      }
+    }
+
+  __ASSERT_DEBUG( aArray.Count() == 0, User::Invariant() );
+
+  // All the data is released.
+  // CCamBufferShare destructor is not public, so cannot call ResetAndDestroy.
+  aArray.Reset();
+
+  PRINT( _L("Camera <= CCamImageSaveActive::ReleaseAllAndDestroy") );
+  }
+
+#if defined(RD_MDS_2_5) && !defined(__WINSCW__) && !defined(__WINS__)
+// -----------------------------------------------------------------------------
+// HarvestingComplete
+//
+// Call Back method from the harvesting client once the harvesting is complete
+// -----------------------------------------------------------------------------
+//
+void CCamImageSaveActive::HarvestingComplete( TDesC& aURI
+#ifdef RD_MDS_2_5        
+                                            , TInt aError 
+#endif // RD_MDS_2_5
+                                             )
+    {
+    PRINT( _L("Camera => CCamImageSaveActive::HarvestingComplete") );
+#ifdef RD_MDS_2_5        
+    PRINT1( _L("Camera <> aError = %d"), aError );
+
+    if ( iController.UiConfigManagerPtr() && 
+         iController.UiConfigManagerPtr()->IsThumbnailManagerAPISupported() && 
+         iSnapArray.Count() &&
+         iNameArray->Count() )
+        {
+        TRAP_IGNORE( DoCreateThumbnailL() ); 
+        }
+
+#endif // RD_MDS_2_5
+    iObserver.HandleFileHarvestingComplete();
+    PRINT( _L("Camera <= CCamImageSaveActive::HarvestingComplete") );
+    }
+
+//
+//CCamImageSaveActive::DeRegisterHarverterClientEvents
+//
+void CCamImageSaveActive::DeRegisterHarverterClientEvents()
+    {
+    PRINT( _L("Camera => CCamImageSaveActive::DeRegisterHarverterClientEvents") );
+
+    if ( iRegisteredForHarvesterEvents && iHarvesterClientConnected )
+        {
+        iHarvesterClient.RemoveObserver( this );
+        iRegisteredForHarvesterEvents = EFalse;
+        iHarvesterClient.Close();
+        iHarvesterClientConnected = EFalse;
+        }
+    else
+        {
+        // do nothing
+        }
+
+    PRINT( _L("Camera <= CCamImageSaveActive::DeRegisterHarverterClientEvents") );
+    }
+
+
+//
+//CCamImageSaveActive::RegisterForHarvesterEvents
+//
+void CCamImageSaveActive::RegisterForHarvesterEvents()
+    {
+    PRINT( _L("Camera => CCamImageSaveActive::RegisterForHarvesterEvents") );
+
+    if ( !iRegisteredForHarvesterEvents && iHarvesterClientConnected )
+        {
+        iHarvesterClient.SetObserver( this );
+        iRegisteredForHarvesterEvents = ETrue;
+        }
+    else
+        {
+        // do nothing
+        }
+
+    PRINT( _L("Camera <= CCamImageSaveActive::RegisterForHarvesterEvents") );
+    }
+
+#endif // defined(RD_MDS_2_5) && !defined(__WINSCW__) && !defined(__WINS__)
+
+// -----------------------------------------------------------------------------
+// CreateThumbnailsL
+//
+// -----------------------------------------------------------------------------
+//
+void CCamImageSaveActive::CreateThumbnailsL( const CCamBurstCaptureArray& aArray )
+    {
+    PRINT( _L("Camera => CCamImageSaveActive::CreateThumbnailsL") );
+    TInt arrayCount = aArray.Count();
+    if ( !iSnapArray.Count() )
+      {
+      iThumbnailRequests.Reset();
+      iThumbnailRequests.ReserveL( arrayCount );
+      }
+    TInt count(0);
+    TInt err(0);
+    
+    for ( TInt i=0; i < arrayCount; i++ )
+        {
+        count = iNameArray->Count();        
+
+        CFbsBitmap* snapshot = new( ELeave ) CFbsBitmap();
+        if ( aArray.Snapshot( i ) )
+            {
+            err = snapshot->Duplicate( aArray.Snapshot( i )->Handle() );
+            }
+        // in case the snapshot is missing, the newly created empty bitmap indicates
+        // the thumbnail is created using the imagefile    
+        if ( !err )
+            {
+            TRAP( err, iSnapArray.AppendL( snapshot ) );            
+            if ( !err ) 
+                {
+                //append filename (includes full path)
+                PRINT1( _L("Camera <> CCamImageSaveActive::CreateThumbnails append file:%S"), &aArray.FileName( i ) );    
+                TRAP( err, iNameArray->AppendL( aArray.FileName( i ) ) );
+                if ( !err )
+                    {
+                    TRAP( err, iThumbnailRequests.AppendL( KErrNotFound ) );
+                    }
+                }
+            if ( err  )
+                {
+                if ( iNameArray->Count() > count )
+                    {
+                    iNameArray->Delete( count );
+                    }
+                if ( iSnapArray.Count() > count )
+                    {
+                    iSnapArray.Remove( count );
+                    }
+                if ( iThumbnailRequests.Count() > count )
+                    {
+                    iThumbnailRequests.Remove( count );
+                    }
+                }
+            }
+        }     
+    PRINT( _L("Camera <= CCamImageSaveActive::CreateThumbnailsL") );
+    }
+
+// -----------------------------------------------------------------------------
+// CCamImageSaveActive::DoCreateThumbnail
+// Add images to album
+// -----------------------------------------------------------------------------
+//
+void CCamImageSaveActive::DoCreateThumbnailL()
+    {
+    PRINT( _L( "Camera => CCamImageSaveActive::DoCreateThumbnailL" ) );     
+    if( !iManager )
+        {
+        PRINT( _L( "Camera <> CCamImageSaveActive::DoCreateThumbnail create manager" ) );         
+        iManager = CThumbnailManager::NewL( *this );
+        }
+    // create object and call thumbnailmanager
+    TSize size = iSnapArray[ 0 ]->SizeInPixels();
+    CThumbnailObjectSource* source;
+    if ( size.iHeight == 0 || size.iWidth == 0 )
+        {
+        PRINT( _L( "Camera <> CCamImageSaveActive::DoCreateThumbnail only URI" ) );         
+        source = CThumbnailObjectSource::NewL( iNameArray->MdcaPoint( 0 ), 
+                                               KNullDesC );
+        }
+    else
+        {
+        PRINT( _L( "Camera <> CCamImageSaveActive::DoCreateThumbnail URI and bitmap" ) );             
+        source = CThumbnailObjectSource::NewL( iSnapArray[ 0 ], 
+                                               iNameArray->MdcaPoint( 0 ) );
+        }
+    PRINT1( _L("Camera <> CCamImageSaveActive::DoCreateThumbnailL  filename:%S"), &iNameArray->MdcaPoint( 0 ) );        
+    CleanupStack::PushL( source );        
+    TThumbnailRequestId requestId = iManager->CreateThumbnails( *source );
+    TInt index = iThumbnailRequests.Count() - iSnapArray.Count();
+    PRINT2( _L( "Camera <> CCamImageSaveActive::DoCreateThumbnailL array index=%d, request id=%d" ), index, requestId );
+    iThumbnailRequests[index] = requestId;
+    CleanupStack::PopAndDestroy( source );
+
+    iNameArray->Delete( 0 );
+    iNameArray->Compress();
+
+    iSnapArray.Remove( 0 );
+    iSnapArray.Compress();
+
+    if ( !IsActive() && iNameArray->Count() > 0  )
+        {
+        SetActiveAndCompleteRequest();
+        }
+    PRINT( _L( "Camera <= CCamImageSaveActive::DoCreateThumbnailL" ) );         
+    }
+
+void CCamImageSaveActive::CancelThumbnail( TInt aSnapshotIndex )
+    {
+    PRINT1( _L( "Camera => CCamImageSaveActive::CancelThumbnail - aSnapshotIndex=%d" ), aSnapshotIndex );
+    if ( aSnapshotIndex >= iThumbnailRequests.Count() )
+        {
+        PRINT( _L( "Camera <= CCamImageSaveActive::CancelThumbnail request array not initialized yet" ) );
+        return;
+        }
+    TThumbnailRequestId requestId = iThumbnailRequests[aSnapshotIndex];
+    if ( requestId != KErrNotFound )
+        {
+        if ( iManager )
+            {
+            PRINT1( _L( "Camera <> CCamImageSaveActive::CancelThumbnail canceling request %d"), requestId );
+            TInt err = iManager->CancelRequest( requestId );
+            PRINT1( _L( "Camera <> CCamImageSaveActive::CancelThumbnail CancelRequest() returned %d"), err );
+            iThumbnailRequests[aSnapshotIndex] = KErrNotFound;
+            }
+        }
+    PRINT( _L( "Camera <= CCamImageSaveActive::CancelThumbnail" ) );
+    }
+void CCamImageSaveActive::ThumbnailPreviewReady( MThumbnailData& aThumbnail, 
+                                                 TThumbnailRequestId aId )
+    {
+	// empty implementation
+    }                                                 
+          
+void CCamImageSaveActive::ThumbnailReady( TInt aError, 
+                                          MThumbnailData& aThumbnail, 
+                                          TThumbnailRequestId aId )
+    {
+    PRINT1( _L( "Camera => CCamImageSaveActive::ThumbnailReady aId=%d" ), aId );
+    for ( TInt i = 0; i < iThumbnailRequests.Count(); i++ )
+        {
+        if ( iThumbnailRequests[i] == aId )
+            {
+            PRINT1( _L( "Camera <> CCamImageSaveActive::ThumbnailReady thumbnail for snapshot %d ready" ), i );
+            iThumbnailRequests[i] = KErrNotFound;
+            }
+        }
+    PRINT( _L( "Camera <= CCamImageSaveActive::ThumbnailReady" ) );
+    }
+                                              
+//  End of File