--- /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