--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailserversession.cpp Tue Jan 26 15:18:05 2010 +0200
@@ -0,0 +1,1327 @@
+/*
+* Copyright (c) 2006-2007 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: Server side session for Thumbnail Manager Server
+ *
+*/
+
+#include <imageconversion.h>
+
+#include "thumbnailserversession.h"
+#include "thumbnailserver.h"
+#include "thumbnailtaskprocessor.h"
+#include "thumbnailmanagerconstants.h"
+#include "thumbnailgeneratetask.h"
+#include "thumbnailscaletask.h"
+#include "thumbnaildecodetask.h"
+#ifdef RD_MDS_2_5
+#include "thumbnailmdsquerytask.h"
+#endif // RD_MDS_2_5
+#include "thumbnaillog.h"
+#include "thumbnailpanic.h"
+
+#include "thumbnailcenrep.h"
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CThumbnailServerSession::CThumbnailServerSession()
+// C++ default constructor can NOT contain any code, that might leave.
+// ---------------------------------------------------------------------------
+//
+CThumbnailServerSession::CThumbnailServerSession(): CSession2()
+ {
+ iBitmapHandle = 0;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CThumbnailServerSession::~CThumbnailServerSession()
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CThumbnailServerSession::~CThumbnailServerSession()
+ {
+ Server()->DropSession(this);
+ }
+
+
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::DispatchMessageL()
+// Message dispatcher.
+// -----------------------------------------------------------------------------
+//
+TInt CThumbnailServerSession::DispatchMessageL( const RMessage2& aMessage )
+ {
+ TInt err( KErrNone );
+
+ switch ( aMessage.Function())
+ {
+ case ERequestThumbByFileHandleAsync:
+ {
+ RequestThumbByFileHandleAsyncL( aMessage );
+ break;
+ }
+ case ERequestThumbByPathAsync:
+ {
+ RequestThumbByPathAsyncL( aMessage );
+ break;
+ }
+ case ERequestSetThumbnailByBuffer:
+ {
+ RequestSetThumbnailByBufferL( aMessage );
+ break;
+ }
+ case ERequestSetThumbnailByBitmap:
+ {
+ RequestSetThumbnailByBitmapL( aMessage );
+ break;
+ }
+ case EReleaseBitmap:
+ {
+ ReleaseBitmap( aMessage );
+ break;
+ }
+ case ECancelRequest:
+ {
+ err = CancelRequest( aMessage );
+ break;
+ }
+ case EChangePriority:
+ {
+ err = ChangePriority( aMessage );
+ break;
+ }
+ case ECreateThumbnails:
+ {
+ CreateThumbnailsL( aMessage );
+ break;
+ }
+ case EDeleteThumbnails:
+ {
+ DeleteThumbnailsL( aMessage );
+ break;
+ }
+ case EDeleteThumbnailsById:
+ {
+ DeleteThumbnailsByIdL( aMessage );
+ break;
+ }
+ case EGetMimeTypeBufferSize:
+ {
+ GetMimeTypeBufferSizeL( aMessage );
+ break;
+ }
+ case EGetMimeTypeList:
+ {
+ GetMimeTypeListL( aMessage );
+ break;
+ }
+ case ERequestThumbByIdAsync:
+ {
+ RequestThumbByIdAsyncL( aMessage );
+ break;
+ }
+ case EUpdateThumbnails:
+ {
+ UpdateThumbnailsL( aMessage );
+ break;
+ }
+ default:
+ {
+ err = KErrUnknown;
+ break;
+ }
+ }
+
+ return err;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CThumbnailServerSession::CreateL()
+// ---------------------------------------------------------------------------
+//
+void CThumbnailServerSession::CreateL()
+ {
+ Server()->AddSession();
+ }
+
+
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::ServiceL()
+// Handles service request messages from clients.
+// -----------------------------------------------------------------------------
+//
+void CThumbnailServerSession::ServiceL( const RMessage2& aMessage )
+ {
+ __ASSERT_DEBUG( !iMessage.Handle(), ThumbnailPanic(
+ EThumbnailMessageNotCompleted ));
+ if ( iMessage.Handle())
+ {
+ iMessage.Complete( KErrUnknown );
+ iMessage = RMessage2();
+ }
+ iMessage = aMessage;
+
+ // clean up possible trash
+ if (iBitmapHandle)
+ {
+ Server()->DeleteBitmapFromPool( iBitmapHandle );
+ iBitmapHandle = 0;
+ }
+ delete iBitmap;
+ iBitmap = NULL;
+ delete iBuffer;
+ iBuffer = NULL;
+ iOriginalSize = TSize();
+
+ TInt ret = KErrNone;
+
+ TRAPD( err,
+ {
+ ret = DispatchMessageL( aMessage );
+ }
+ );
+ if ( iMessage.Handle())
+ {
+ iMessage.Complete( ConvertSqlErrToE32Err( err != KErrNone ? err : ret ));
+ iMessage = RMessage2();
+ }
+ else
+ {
+ return;
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::Server()
+// Returns the server pointer.
+// -----------------------------------------------------------------------------
+//
+CThumbnailServer* CThumbnailServerSession::Server()
+ {
+ return ( CThumbnailServer* )( CSession2::Server());
+ }
+
+
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::Cancel()
+// -----------------------------------------------------------------------------
+//
+void CThumbnailServerSession::Cancel()
+ {
+ }
+
+
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::UpdateThumbnailsL()
+// -----------------------------------------------------------------------------
+//
+void CThumbnailServerSession::UpdateThumbnailsL( const RMessage2& aMessage )
+ {
+ TN_DEBUG1( "CThumbnailServerSession::UpdateThumbnailsL()" );
+
+ if(aMessage.Int1() != KCheckValue)
+ {
+ TN_DEBUG1( "CThumbnailServerSession::UpdateThumbnailsL() - error in aMessage - leaving" );
+ User::Leave(KErrArgument);
+ }
+
+ // read message params
+ aMessage.ReadL( 0, iRequestParams );
+ const TThumbnailRequestParams& params = iRequestParams();
+
+ TBool finished = Server()->UpdateThumbnailsL( params.iThumbnailId, params.iFileName, params.iOrientation, params.iModified );
+
+ if (finished)
+ {
+ TN_DEBUG1( "CThumbnailServerSession::UpdateThumbnailsL() - finished" );
+
+ aMessage.Complete( KErrNone );
+ }
+ else
+ {
+ TN_DEBUG1( "CThumbnailServerSession::UpdateThumbnailsL() - need to recreate thumbs" );
+
+ // need to create new thumbs
+ aMessage.Complete( KThumbnailErrThumbnailNotFound );
+ }
+
+ iMessage = RMessage2();
+ }
+
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::RequestThumbByIdAsyncL()
+// -----------------------------------------------------------------------------
+//
+void CThumbnailServerSession::RequestThumbByIdAsyncL( const RMessage2&
+ aMessage )
+ {
+#ifdef _DEBUG
+ TTime aStart, aStop;
+ aStart.UniversalTime();
+#endif
+
+ TN_DEBUG1( "CThumbnailServerSession::RequestThumbByIdAsyncL() - begin" );
+
+ if(aMessage.Int1() != KCheckValue)
+ {
+ TN_DEBUG1( "CThumbnailServerSession::RequestThumbByIdAsync() - error in aMessage - leaving" );
+ User::Leave(KErrArgument);
+ }
+
+ aMessage.ReadL( 0, iRequestParams );
+ const TThumbnailRequestParams& params = iRequestParams();
+ TRAPD( err, Server()->FetchThumbnailL( params.iThumbnailId, iBitmap, iBuffer,
+ params.iThumbnailSize, iOriginalSize ));
+ if ( !err && iBitmap )
+ {
+ TN_DEBUG1(
+ "CThumbnailServerSession::RequestThumbByIdAsyncL() - found existing thumbnail- bitmap" );
+
+ ProcessBitmapL();
+ }
+ else if ( !err && iBuffer)
+ {
+ TN_DEBUG1(
+ "CThumbnailServerSession::RequestThumbByIdAsyncL() - found existing thumbnail- jpeg" );
+
+ CThumbnailDecodeTask* task = new( ELeave )CThumbnailDecodeTask( Server()
+ ->Processor(), * Server(), iBuffer, params.iPriority, params.iDisplayMode );
+
+ CleanupStack::PushL( task );
+ task->SetMessageData( TThumbnailServerRequestId( this, params.iRequestId ), iMessage );
+ Server()->QueueTaskL( task );
+ CleanupStack::Pop( task ); // owned by processor now
+
+ // Decode task is now responsible for completing the message
+ iMessage = RMessage2();
+
+ //CThumbnailDecodeTask is responsible freeing
+ iBuffer = NULL;
+ }
+ else if( err == KErrCompletion )
+ {
+ // If thumbnail of requested size is blacklisted, fetching is left with KErrCompletion
+ TN_DEBUG1(
+ "CThumbnailServerSession::RequestThumbByIdAsyncL() - thumbnail blacklisted" );
+ aMessage.Complete( err );
+ iMessage = RMessage2();
+ }
+ else
+ {
+ TN_DEBUG2(
+ "CThumbnailServerSession::RequestThumbByIdAsyncL() - thumbnail not found ( query path from MDS ), err=%d ", err );
+
+#ifdef RD_MDS_2_5
+ // try to query path from MDS
+ CThumbnailMDSQueryTask* task = new( ELeave )CThumbnailMDSQueryTask(
+ Server()->Processor(), params.iPriority + 1, Server()->GetMdESession(), *Server());
+
+ CleanupStack::PushL( task );
+ task->QueryPathByIdL(params.iThumbnailId);
+ task->SetMessageData( TThumbnailServerRequestId( this, params.iRequestId ), iMessage );
+ Server()->QueueTaskL( task );
+ CleanupStack::Pop( task ); // owned by processor now
+
+ // query task is now responsible for completing the message
+ iMessage = RMessage2();
+#else
+ User::Leave(KThumbnailErrThumbnailNotFound);
+#endif // RD_MDS_2_5
+
+ }
+
+#ifdef _DEBUG
+ aStop.UniversalTime();
+ TN_DEBUG2( "CThumbnailStore::RequestThumbByIdAsyncL() request took %d ms", (TInt)aStop.MicroSecondsFrom(aStart).Int64()/1000 );
+#endif
+
+ TN_DEBUG1("CThumbnailServerSession::RequestThumbByIdAsyncL() - end" );
+ }
+
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::RequestThumbByFileHandleAsync()
+// -----------------------------------------------------------------------------
+//
+void CThumbnailServerSession::RequestThumbByFileHandleAsyncL( const RMessage2&
+ aMessage )
+ {
+ TN_DEBUG1( "CThumbnailServerSession::RequestThumbByFileHandleAsyncL()" );
+
+ if(aMessage.Int1() != KCheckValue)
+ {
+ TN_DEBUG1( "CThumbnailServerSession::RequestThumbByFileHandleAsync() - error in aMessage - leaving" );
+ User::Leave(KErrArgument);
+ }
+
+ aMessage.ReadL( 0, iRequestParams );
+ const TThumbnailRequestParams& params = iRequestParams();
+
+ RFile64 file;
+ User::LeaveIfError( file.AdoptFromClient( aMessage, 2, 3 ));
+
+ ResolveMimeTypeL(&file);
+
+ if(params.iThumbnailSize == EFullScreenThumbnailSize ||
+ params.iThumbnailSize == EGridThumbnailSize ||
+ params.iThumbnailSize == EListThumbnailSize )
+ {
+ TInt sourceType = TThumbnailPersistentSize::EUnknownSourceType;
+ sourceType = Server()->SourceTypeFromMimeType( params.iMimeType );
+ ModifyThumbnailSize(sourceType);
+ }
+
+ // CreateThumbnails
+ if (params.iControlFlags == EThumbnailGeneratePersistentSizesOnly)
+ {
+ CleanupClosePushL( file );
+ CreateGenerateTaskFromFileHandleL( &file );
+ CleanupStack::Pop( &file );
+ }
+ // single thumbnail request
+ else
+ {
+ TRAPD( err, FetchThumbnailL());
+
+ if ( !err && iBitmap )
+ {
+ TN_DEBUG1( "CThumbnailServerSession::RequestThumbByFileHandleAsyncL() - found existing thumbnail - bitmap " );
+
+ // Thumbnail already stored
+ file.Close();
+ TN_DEBUG1("CThumbnailServerSession::RequestThumbByFileHandleAsyncL - file handle closed");
+
+ ProcessBitmapL();
+ }
+ else if ( (err == KErrNotFound || err == KErrAccessDenied) &&
+ !(params.iFlags& CThumbnailManager::EDoNotCreate) )
+ {
+ CreateGenerateTaskFromFileHandleL( &file);
+ }
+ else if (!err && iBuffer)
+ {
+ TN_DEBUG1(
+ "CThumbnailServerSession::RequestThumbByFileHandleAsyncL() - found existing thumbnail - jpeg " );
+
+ CThumbnailDecodeTask* task = new( ELeave )CThumbnailDecodeTask( Server()
+ ->Processor(), * Server(), iBuffer, params.iPriority, params.iDisplayMode );
+
+ CleanupStack::PushL( task );
+ task->SetMessageData( TThumbnailServerRequestId( this, params.iRequestId ), iMessage );
+ Server()->QueueTaskL( task );
+ CleanupStack::Pop( task ); // owned by processor now
+
+ // Decode task is now responsible for completing the message
+ iMessage = RMessage2();
+
+ //CThumbnailDecodeTask is responsible freeing
+ iBuffer = NULL;
+ file.Close();
+ TN_DEBUG1("CThumbnailServerSession::RequestThumbByFileHandleAsyncL - file handle closed");
+ }
+ else
+ {
+ TN_DEBUG2(
+ "CThumbnailServerSession::RequestThumbByFileHandleAsyncL() - thumbnail not found, err=%d", err );
+ aMessage.Complete( ConvertSqlErrToE32Err( err ));
+ iMessage = RMessage2();
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::RequestThumbByPathAsync()
+// -----------------------------------------------------------------------------
+//
+void CThumbnailServerSession::RequestThumbByPathAsyncL( const RMessage2&
+ aMessage )
+ {
+ TN_DEBUG1( "CThumbnailServerSession::RequestThumbByPathAsyncL()" );
+
+#ifdef _DEBUG
+ TTime aStart, aStop;
+ aStart.UniversalTime();
+#endif
+
+ if(aMessage.Int1() != KCheckValue)
+ {
+ TN_DEBUG1( "CThumbnailServerSession::RequestThumbByPathAsync() - error in aMessage - leaving" );
+ User::Leave(KErrArgument);
+ }
+
+ aMessage.ReadL( 0, iRequestParams );
+ const TThumbnailRequestParams& params = iRequestParams();
+
+ ResolveMimeTypeL(NULL);
+
+ if(params.iThumbnailSize == EFullScreenThumbnailSize ||
+ params.iThumbnailSize == EGridThumbnailSize ||
+ params.iThumbnailSize == EListThumbnailSize )
+ {
+ TInt sourceType = TThumbnailPersistentSize::EUnknownSourceType;
+ sourceType = Server()->SourceTypeFromMimeType( params.iMimeType );
+ ModifyThumbnailSize(sourceType);
+ }
+
+ // should always be true
+ if (params.iControlFlags != EThumbnailGeneratePersistentSizesOnly)
+ {
+ TRAPD( err, FetchThumbnailL());
+
+ if ( !err && iBitmap )
+ {
+ TN_DEBUG1(
+ "CThumbnailServerSession::RequestThumbByPathAsyncL() - found existing thumbnail- bitmap" );
+
+ ProcessBitmapL();
+ }
+ else if ( !err && iBuffer)
+ {
+ TN_DEBUG1(
+ "CThumbnailServerSession::RequestThumbByPathAsyncL() - found existing thumbnail- jpeg" );
+
+ CThumbnailDecodeTask* task = new( ELeave )CThumbnailDecodeTask( Server()
+ ->Processor(), * Server(), iBuffer, params.iPriority, params.iDisplayMode );
+
+ CleanupStack::PushL( task );
+ task->SetMessageData( TThumbnailServerRequestId( this, params.iRequestId ), iMessage );
+ Server()->QueueTaskL( task );
+ CleanupStack::Pop( task ); // owned by processor now
+
+ // Decode task is now responsible for completing the message
+ iMessage = RMessage2();
+
+ //CThumbnailDecodeTask is responsible freeing
+ iBuffer = NULL;
+ }
+ else if( err == KErrCompletion )
+ {
+ // If thumbnail of requested size is blacklisted, fetching is left with KErrCompletion
+ TN_DEBUG1(
+ "CThumbnailServerSession::RequestThumbByIdAsyncL() - thumbnail blacklisted" );
+ aMessage.Complete( err );
+ iMessage = RMessage2();
+ }
+ else
+ {
+ TN_DEBUG2(
+ "CThumbnailServerSession::RequestThumbByPathAsyncL() - thumbnail not found, err = %d", err );
+
+ if ( (err == KErrNotFound || err == KErrAccessDenied) &&
+ !(params.iFlags& CThumbnailManager::EDoNotCreate) )
+ {
+ // Special error code so that the client side can open the file
+ // and retry the request using file handle
+ err = KThumbnailErrThumbnailNotFound;
+ }
+ else
+ {
+ User::Leave(err);
+ }
+
+#ifdef RD_MDS_2_5
+ // try to query ID from MDS
+ CThumbnailMDSQueryTask* task = new( ELeave )CThumbnailMDSQueryTask(
+ Server()->Processor(), params.iPriority + 1, Server()->GetMdESession(), *Server());
+
+ CleanupStack::PushL( task );
+ task->SetUpdateToDb( EFalse );
+ task->QueryIdByPathL( params.iFileName );
+ task->SetMessageData( TThumbnailServerRequestId( this, params.iRequestId ), iMessage );
+ Server()->QueueTaskL( task );
+ CleanupStack::Pop( task ); // owned by processor now
+
+ // query task is now responsible for completing the message
+ iMessage = RMessage2();
+#else
+ User::Leave(err);
+#endif // RD_MDS_2_5
+
+ }
+ }
+
+#ifdef _DEBUG
+ aStop.UniversalTime();
+ TN_DEBUG2( "CThumbnailStore::RequestThumbByPathAsyncL() request took %d ms", (TInt)aStop.MicroSecondsFrom(aStart).Int64()/1000 );
+#endif
+ }
+
+void CThumbnailServerSession::RequestSetThumbnailByBufferL( const RMessage2& aMessage )
+ {
+ TN_DEBUG1( "CThumbnailServerSession::RequestSetThumbnailByBufferL()" );
+
+ if(aMessage.Int3() != KCheckValue)
+ {
+ TN_DEBUG1( "CThumbnailServerSession::RequestSetThumbnailByBufferL() - error in aMessage - leaving" );
+ User::Leave(KErrArgument);
+ }
+
+ aMessage.ReadL( 0, iRequestParams );
+ const TThumbnailRequestParams& params = iRequestParams();
+
+ if(params.iThumbnailSize != EUnknownThumbnailSize)
+ {
+ Server()->DeleteThumbnailsL( params.iTargetUri);
+ }
+
+ if(params.iThumbnailSize == EFullScreenThumbnailSize ||
+ params.iThumbnailSize == EGridThumbnailSize ||
+ params.iThumbnailSize == EListThumbnailSize )
+ {
+ TInt sourceType = TThumbnailPersistentSize::EUnknownSourceType;
+ TDataType mimetype;
+ Server()->MimeTypeFromFileExt( params.iTargetUri, mimetype );
+ sourceType = Server()->SourceTypeFromMimeType( mimetype );
+ ModifyThumbnailSize(sourceType);
+ }
+
+ TInt bufferSize = aMessage.Int2();
+ HBufC8* buffer = HBufC8::NewMaxLC( bufferSize );
+ TPtr8 ptr = buffer->Des();
+ aMessage.ReadL( 1 /* buffer pointer */, ptr );
+
+ CreateGenerateTaskFromBufferL( buffer );
+ CleanupStack::Pop( buffer );
+ }
+
+void CThumbnailServerSession::RequestSetThumbnailByBitmapL( const RMessage2& aMessage )
+ {
+ TN_DEBUG1( "CThumbnailServerSession::RequestSetThumbnailByBitmapL()" );
+
+ if(aMessage.Int2() != KCheckValue)
+ {
+ TN_DEBUG1( "CThumbnailServerSession::RequestSetThumbnailByBitmapL() - error in aMessage - leaving" );
+ User::Leave(KErrArgument);
+ }
+
+ aMessage.ReadL( 0, iRequestParams );
+ const TThumbnailRequestParams& params = iRequestParams();
+
+ TInt bitmapHandle = aMessage.Int1();
+ TThumbnailServerRequestId &reqId = (TThumbnailServerRequestId&)params.iRequestId;
+
+ // get bitmap
+ CFbsBitmap* bitmap = new( ELeave )CFbsBitmap();
+ CleanupStack::PushL( bitmap );
+ User::LeaveIfError( bitmap->Duplicate( bitmapHandle ) );
+ Server()->AddBitmapToPoolL( reqId.iSession, bitmap );
+ CleanupStack::Pop( bitmap );
+ iBitmapHandle = bitmap->Handle();
+
+ RArray < TThumbnailPersistentSize >* missingSizes = NULL;
+
+ // source type
+ TDataType mimeType;
+ TInt sourceType = 0;
+ TInt err = Server()->MimeTypeFromFileExt( params.iTargetUri, mimeType );
+ TBool missingIDs(EFalse);
+
+ // get missing sizes
+ if ( err == KErrNone && ( params.iControlFlags & EThumbnailGeneratePersistentSizesOnly ) != 0 )
+ {
+ sourceType = Server()->SourceTypeFromMimeType( mimeType );
+
+ missingSizes = new (ELeave) RArray < TThumbnailPersistentSize >;
+ CleanupClosePushL( *missingSizes );
+
+ Server()->GetMissingSizesAndIDsL( params.iTargetUri, sourceType, *missingSizes, missingIDs);
+
+ if ( missingSizes->Count() == 0)
+ {
+ // all thumbs already exist
+ CleanupStack::PopAndDestroy( missingSizes );
+ delete missingSizes;
+ missingSizes = NULL;
+ }
+ }
+
+ // if missing sizes, create scale tasks
+ if ( missingSizes )
+ {
+ const TInt count = missingSizes->Count();
+
+ TSize bitmapSize = bitmap->SizeInPixels();
+
+ for ( TInt i( 0 ); i < count; i++ )
+ {
+ if( bitmapSize.iWidth < bitmapSize.iHeight )
+ {
+ TInt height = (*missingSizes)[i].iSize.iHeight;
+ (*missingSizes)[i].iSize.iHeight = (*missingSizes)[i].iSize.iWidth;
+ (*missingSizes)[i].iSize.iWidth = height;
+ TN_DEBUG1( "CThumbnailServerSession::RequestSetThumbnailByBitmapL() - portrait");
+ }
+
+ CThumbnailScaleTask* scaleTask = CThumbnailScaleTask::NewL( Server()->Processor(),
+ *Server(), params.iTargetUri, bitmap, bitmapSize,
+ (*missingSizes)[i].iSize, (*missingSizes)[i].iCrop, params.iDisplayMode,
+ KMaxPriority, KNullDesC, (*missingSizes)[i].iType, params.iThumbnailId, EFalse, EFalse );
+ CleanupStack::PushL( scaleTask );
+ scaleTask->SetDoStore( ETrue );
+ //increase priority, scale needs to run before ID update below
+ scaleTask->SetPriority( params.iPriority + 1 );
+ Server()->Processor().AddTaskL( scaleTask );
+ CleanupStack::Pop( scaleTask );
+
+ if( i == count-1 )
+ {
+ // scaleTask is now responsible for completing the RMessage
+ scaleTask->SetMessageData( reqId, iMessage );
+ iMessage = RMessage2();
+ }
+ }
+
+ TN_DEBUG3("CThumbnailServerSession::RequestSetThumbnailByBitmapL() ID = %d, missingIDs = %d", params.iThumbnailId, missingIDs);
+ }
+ else
+ {
+ // complete message
+ aMessage.Complete( KErrNone );
+ iMessage = RMessage2();
+ }
+
+ if ( missingSizes )
+ {
+ CleanupStack::PopAndDestroy( missingSizes );
+ delete missingSizes;
+ missingSizes = NULL;
+ }
+
+ Server()->DeleteBitmapFromPool( iBitmapHandle );
+ iBitmapHandle = 0;
+ bitmap = NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::CreateThumbnailsL()
+// Create thumbnails for given object file
+// -----------------------------------------------------------------------------
+//
+void CThumbnailServerSession::CreateThumbnailsL( const RMessage2& aMessage )
+ {
+ RFile64 file;
+ CleanupClosePushL( file );
+ User::LeaveIfError( file.AdoptFromClient( aMessage, 1, 2 ));
+
+ CreateGenerateTaskFromFileHandleL( &file);
+
+ CleanupStack::Pop( &file );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::CreateGenerateTaskL()
+// Create a task to generate a new thumbnail
+// -----------------------------------------------------------------------------
+//
+void CThumbnailServerSession::CreateGenerateTaskFromFileHandleL( RFile64* aFile)
+ {
+ const TThumbnailRequestParams& params = iRequestParams();
+
+ TN_DEBUG2(
+ "CThumbnailServerSession::CreateGenerateTaskFromFileHandleL() -- create thumbnail generation task for %S", ¶ms.iFileName );
+
+ TBool missingIDs = EFalse;
+
+ RArray < TThumbnailPersistentSize >* missingSizes = NULL;
+
+ // get missing sizes
+ if ( ( params.iControlFlags & EThumbnailGeneratePersistentSizesOnly ) != 0 )
+ {
+ TInt sourceType = TThumbnailPersistentSize::EUnknownSourceType;
+ sourceType = Server()->SourceTypeFromMimeType( params.iMimeType );
+ missingSizes = new (ELeave) RArray < TThumbnailPersistentSize >;
+ CleanupClosePushL( *missingSizes );
+
+ Server()->GetMissingSizesAndIDsL( params.iFileName, sourceType, *missingSizes, missingIDs );
+#ifdef RD_MDS_2_5
+ if( missingIDs )
+ {
+ TN_DEBUG1("CThumbnailServerSession::CreateGenerateTaskFromFileHandleL() some IDs missing");
+
+ if( params.iThumbnailId == KNoId)
+ {
+ TN_DEBUG1("CThumbnailServerSession::CreateGenerateTaskFromFileHandleL() query fro MDS");
+ // try to query ID from MDS
+ CThumbnailMDSQueryTask* task = new( ELeave )CThumbnailMDSQueryTask(
+ Server()->Processor(), params.iPriority + 1, Server()->GetMdESession(), *Server());
+
+ CleanupStack::PushL( task );
+ task->QueryIdByPathL( params.iFileName );
+
+ task->SetMessageData( TThumbnailServerRequestId( this, params.iRequestId ) );
+ Server()->QueueTaskL( task );
+ CleanupStack::Pop( task ); // owned by processor now
+ TN_DEBUG1("CThumbnailServerSession::CreateGenerateTaskFromFileHandleL() query from MDS queued" );
+ }
+ else
+ {
+ TN_DEBUG2("CThumbnailServerSession::CreateGenerateTaskFromFileHandleL() got ID %d from params", params.iThumbnailId);
+ TRAP_IGNORE( Server()->UpdateIDL(params.iFileName, params.iThumbnailId ) );
+ }
+ }
+#endif // RD_MDS_2_5
+
+ if ( missingSizes->Count() == 0)
+ {
+ // all thumbs already exist
+ CleanupStack::PopAndDestroy( missingSizes );
+ delete missingSizes;
+ if( aFile )
+ {
+ aFile->Close();
+ }
+ return;
+ }
+ }
+
+ // priority
+ TInt priority = params.iPriority;
+ if ( priority > KMaxGeneratePriority )
+ {
+ priority = KMaxGeneratePriority;
+ }
+
+ // create new task
+ if( !aFile)
+ {
+ User::Leave( KErrArgument );
+ }
+ CleanupClosePushL( *aFile );
+ CThumbnailGenerateTask* task = new( ELeave )CThumbnailGenerateTask( Server()
+ ->Processor(), * Server(), aFile, NULL, ¶ms.iMimeType, params.iFlags,
+ params.iSize, params.iDisplayMode, priority, missingSizes, params.iTargetUri,
+ params.iThumbnailSize, params.iThumbnailId, params.iQualityPreference );
+
+ // do not store bitmaps to server pool when generating only
+ if( params.iControlFlags & EThumbnailGeneratePersistentSizesOnly )
+ {
+ task->ScaledBitmapToPool( EFalse );
+ }
+
+ CleanupStack::Pop( aFile );
+
+ CleanupStack::PushL( task );
+ task->SetMessageData( TThumbnailServerRequestId( this, params.iRequestId ),
+ iMessage );
+ Server()->QueueTaskL( task );
+ CleanupStack::Pop( task ); // owned by processor now
+
+ if ( missingSizes )
+ {
+ CleanupStack::Pop( missingSizes );
+ }
+
+ // Generate task is now responsible for completing the message
+ iMessage = RMessage2();
+ }
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::CreateGenerateTaskL()
+// Create a task to generate a new thumbnail
+// -----------------------------------------------------------------------------
+//
+void CThumbnailServerSession::CreateGenerateTaskFromBufferL( TDesC8* aBuffer )
+ {
+ const TThumbnailRequestParams& params = iRequestParams();
+
+ TN_DEBUG2(
+ "CThumbnailServerSession::CreateGenerateTaskFromBufferL() -- create thumbnail generation task for %S", ¶ms.iTargetUri );
+
+ if(aBuffer && params.iMimeType.Des().Match( KVideoMime ) == 0 )
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+ TInt sourceType = TThumbnailPersistentSize::EUnknownSourceType;
+
+ TDataType mimetype;
+ TInt ret = Server()->MimeTypeFromFileExt( params.iTargetUri, mimetype );
+ if(ret == KErrNotFound)
+ {
+ Server()->Fs().ShareProtected();
+ RFile64 file;
+ CleanupClosePushL( file );
+
+ User::LeaveIfError( file.Open( Server()->Fs(), params.iTargetUri, EFileShareReadersOrWriters ));
+ TN_DEBUG2( "CThumbnailServerSession::CreateGenerateTaskFromBufferL - file handle opened for %S", ¶ms.iFileName );
+
+ mimetype = Server()->ResolveMimeTypeL(file);
+
+ file.Close();
+ TN_DEBUG1("CThumbnailServerSession::CreateGenerateTaskFromBufferL - file handle closed");
+
+ CleanupStack::Pop( &file );
+ }
+
+ sourceType = Server()->SourceTypeFromMimeType( mimetype );
+
+ RArray < TThumbnailPersistentSize >* missingSizes = NULL;
+
+ // get missing sizes
+ if ( ( params.iControlFlags & EThumbnailGeneratePersistentSizesOnly ) != 0 )
+ {
+ missingSizes = new (ELeave) RArray < TThumbnailPersistentSize >;
+ CleanupClosePushL( *missingSizes );
+
+ TBool missingIDs;
+ Server()->GetMissingSizesAndIDsL( params.iTargetUri, sourceType, *missingSizes, missingIDs );
+
+ if ( missingSizes->Count() == 0)
+ {
+ // all thumbs already exist
+ CleanupStack::PopAndDestroy( missingSizes );
+ delete missingSizes;
+ if ( aBuffer)
+ {
+ delete aBuffer;
+ aBuffer = NULL;
+ }
+ return;
+ }
+ }
+
+ // priority
+ TInt priority = params.iPriority;
+ if ( priority > KMaxGeneratePriority )
+ {
+ priority = KMaxGeneratePriority;
+ }
+
+ // create new task
+ if( !aBuffer)
+ {
+ User::Leave( KErrArgument );
+ }
+
+ CThumbnailGenerateTask* task = new( ELeave )CThumbnailGenerateTask( Server()
+ ->Processor(), * Server(), NULL, aBuffer, ¶ms.iMimeType, params.iFlags,
+ params.iSize, params.iDisplayMode, priority, missingSizes, params.iTargetUri,
+ params.iThumbnailSize, params.iThumbnailId, params.iQualityPreference );
+
+ // do not store bitmaps to server pool when generating only
+ if( params.iControlFlags & EThumbnailGeneratePersistentSizesOnly )
+ {
+ task->ScaledBitmapToPool( EFalse );
+ }
+
+ CleanupStack::PushL( task );
+ task->SetMessageData( TThumbnailServerRequestId( this, params.iRequestId ),
+ iMessage );
+ Server()->QueueTaskL( task );
+ CleanupStack::Pop( task ); // owned by processor now
+
+ if ( missingSizes )
+ {
+ CleanupStack::Pop( missingSizes );
+ }
+
+ // Generate task is now responsible for completing the message
+ iMessage = RMessage2();
+ }
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::FetchThumbnailL()
+// Fetch thumbnail data from database
+// -----------------------------------------------------------------------------
+//
+void CThumbnailServerSession::FetchThumbnailL()
+ {
+ TN_DEBUG1("CThumbnailServerSession::FetchThumbnailL()");
+ __ASSERT_DEBUG( !iBitmap, ThumbnailPanic( EThumbnailBitmapNotReleased ));
+
+ delete iBitmap;
+ iBitmap = NULL;
+
+ TThumbnailRequestParams& params = iRequestParams();
+
+ if ( params.iThumbnailSize != EUnknownThumbnailSize &&
+ params.iThumbnailSize != ECustomThumbnailSize )
+ {
+ TThumbnailPersistentSize & persistentSize = Server()->PersistentSizeL( params.iThumbnailSize );
+ params.iSize = persistentSize.iSize;
+ }
+
+ if( params.iFileName != KNullDesC )
+ {
+ TN_DEBUG4( "CThumbnailServerSession::FetchThumbnailL( TNId==%d ThumbnailSize=%d ( Path=%S ))",
+ params.iThumbnailId, params.iThumbnailSize, ¶ms.iFileName );
+ Server()->FetchThumbnailL( params.iFileName, iBitmap, iBuffer, params.iThumbnailSize, iOriginalSize);
+ }
+ else
+ {
+ TN_DEBUG3( "CThumbnailServerSession::FetchThumbnailL(Path=%S ThumbnailSize=%d)",
+ ¶ms.iFileName, params.iThumbnailSize );
+ Server()->FetchThumbnailL( params.iThumbnailId, iBitmap, iBuffer, params.iThumbnailSize, iOriginalSize );
+ }
+#ifdef _DEBUG
+ if( iBitmap)
+ {
+ TN_DEBUG4( "CThumbnailServerSession::FetchThumbnailL() size %d x %d displaymode %d", iBitmap->SizeInPixels().iWidth, iBitmap->SizeInPixels().iHeight, iBitmap->DisplayMode());
+ }
+#endif
+ }
+
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::ProcessBitmapL()
+// Process a fetched bitmap by creating scale tasks or by returning the
+// bitmap as such.
+// -----------------------------------------------------------------------------
+//
+void CThumbnailServerSession::ProcessBitmapL()
+ {
+ TThumbnailRequestParams& params = iRequestParams();
+
+ // in import case store bitmap
+ if (params.iTargetUri != KNullDesC)
+ {
+ Server()->StoreThumbnailL( params.iTargetUri, iBitmap, iOriginalSize,
+ params.iFlags& CThumbnailManager::ECropToAspectRatio, params.iThumbnailSize, params.iThumbnailId );
+ }
+
+ // No need to scale, return iBitmap directly
+ Server()->AddBitmapToPoolL( this, iBitmap );
+ CFbsBitmap* bitmap = iBitmap;
+ iBitmap = NULL; // owned by server now
+
+ params.iBitmapHandle = bitmap->Handle();
+ const TSize bitmapSize = bitmap->SizeInPixels();
+
+ if ( params.iQualityPreference == CThumbnailManager
+ ::EOptimizeForQualityWithPreview && bitmapSize.iWidth <
+ params.iSize.iWidth && bitmapSize.iHeight < params.iSize.iHeight &&
+ bitmapSize.iWidth < iOriginalSize.iWidth && bitmapSize.iHeight <
+ iOriginalSize.iHeight )
+ {
+ // This is a non-scaled preview bitmap
+ params.iControlFlags = EThumbnailPreviewThumbnail;
+ }
+
+ if ( iMessage.Handle() )
+ {
+ iMessage.WriteL( 0, iRequestParams );
+ iMessage.Complete( KErrNone );
+ iMessage = RMessage2();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::ReleaseBitmap()
+// Release bitmap from bitmap pool
+// -----------------------------------------------------------------------------
+//
+void CThumbnailServerSession::ReleaseBitmap( const RMessage2& aMessage )
+ {
+ TN_DEBUG2( "CThumbnailServerSession::ReleaseBitmap(%d)", aMessage.Int0());
+ Server()->DeleteBitmapFromPool( aMessage.Int0());
+ }
+
+
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::CancelRequest()
+// Cancel pending request.
+// -----------------------------------------------------------------------------
+//
+TInt CThumbnailServerSession::CancelRequest( const RMessage2& aMessage )
+ {
+ const TThumbnailServerRequestId requestId( this, aMessage.Int0());
+ const TInt err = Server()->DequeTask( requestId );
+ TN_DEBUG4(
+ "CThumbnailServerSession::CancelRequest(0x%08x/%d) - returning %d",
+ requestId.iSession, requestId.iRequestId, err );
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::ChangePriority()
+// Change priority of pending request.
+// -----------------------------------------------------------------------------
+//
+TInt CThumbnailServerSession::ChangePriority( const RMessage2& aMessage )
+ {
+ const TThumbnailServerRequestId requestId( this, aMessage.Int0());
+ const TInt newPriority = aMessage.Int1();
+
+ const TInt err = Server()->ChangeTaskPriority( requestId, newPriority );
+ TN_DEBUG5(
+ "CThumbnailServerSession::ChangePriority(0x%08x/%d, %d) - returning %d",
+ requestId.iSession, requestId.iRequestId, newPriority, err );
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::DeleteThumbnailsL()
+// Delete thumbnails for given object file
+// -----------------------------------------------------------------------------
+//
+void CThumbnailServerSession::DeleteThumbnailsL( const RMessage2& aMessage )
+ {
+ if(aMessage.Int2() != KCheckValue)
+ {
+ TN_DEBUG1( "CThumbnailServerSession::DeleteThumbnailsL() - error in aMessage - leaving" );
+ User::Leave(KErrArgument);
+ }
+
+ HBufC* fileName = HBufC::NewLC( KMaxFileName );
+ TPtr ptr = fileName->Des();
+ aMessage.ReadL( 1, ptr );
+ Server()->DeleteThumbnailsL( ptr );
+ CleanupStack::PopAndDestroy( fileName );
+
+ aMessage.Complete( KErrNone );
+ iMessage = RMessage2();
+ }
+
+// -----------------------------------------------------------------------------
+// CThumbnailServerSession::DeleteThumbnailsByIdL()
+// Delete thumbnails by TThumbnailId.
+// -----------------------------------------------------------------------------
+//
+void CThumbnailServerSession::DeleteThumbnailsByIdL( const RMessage2& aMessage )
+ {
+ if(aMessage.Int2() != KCheckValue)
+ {
+ TN_DEBUG1( "CThumbnailServerSession::DeleteThumbnailsByIdL() - error in aMessage - leaving" );
+ User::Leave(KErrArgument);
+ }
+
+ // read message params
+ aMessage.ReadL( 0, iRequestParams );
+ const TThumbnailRequestParams& params = iRequestParams();
+
+ TThumbnailId id = params.iThumbnailId;
+ Server()->DeleteThumbnailsByIdL( id );
+
+ aMessage.Complete( KErrNone );
+ iMessage = RMessage2();
+ }
+
+// -----------------------------------------------------------------------------
+// Get the required size (in characters) for a buffer that contains the
+// list of supported MIME types
+// -----------------------------------------------------------------------------
+//
+void CThumbnailServerSession::GetMimeTypeBufferSizeL( const RMessage2& aMessage
+ )
+ {
+ TPckgBuf < TInt > buf;
+ buf() = Server()->GetMimeTypeBufferSize();
+ aMessage.WriteL( 0, buf );
+ }
+
+// -----------------------------------------------------------------------------
+// Get the list of supported MIME types and store them in the buffer
+// allocated by the client.
+// -----------------------------------------------------------------------------
+//
+void CThumbnailServerSession::GetMimeTypeListL( const RMessage2& aMessage )
+ {
+ TInt len = aMessage.GetDesMaxLengthL( 0 );
+ HBufC* buf = HBufC::NewLC( len );
+ TPtr ptr = buf->Des();
+ Server()->GetMimeTypeList( ptr );
+ aMessage.WriteL( 0, * buf );
+ CleanupStack::PopAndDestroy( buf );
+ }
+
+// ---------------------------------------------------------------------------
+// CThumbnailServerSession::ModifyThumbnailSize
+// ---------------------------------------------------------------------------
+//
+void CThumbnailServerSession::ModifyThumbnailSize( TInt aSourceType )
+ {
+ TThumbnailRequestParams& params = iRequestParams();
+ if(aSourceType == TThumbnailPersistentSize::EImage)
+ {
+ if(params.iThumbnailSize == EFullScreenThumbnailSize)
+ {
+ params.iThumbnailSize = EImageFullScreenThumbnailSize;
+ }
+ else if(params.iThumbnailSize == EGridThumbnailSize)
+ {
+ params.iThumbnailSize = EImageGridThumbnailSize;
+ }
+ else if(params.iThumbnailSize == EListThumbnailSize)
+ {
+ params.iThumbnailSize = EImageListThumbnailSize;
+ }
+ }
+ else if(aSourceType == TThumbnailPersistentSize::EVideo)
+ {
+ if(params.iThumbnailSize == EFullScreenThumbnailSize)
+ {
+ params.iThumbnailSize = EVideoFullScreenThumbnailSize;
+ }
+ else if(params.iThumbnailSize == EGridThumbnailSize)
+ {
+ params.iThumbnailSize = EVideoGridThumbnailSize;
+ }
+ else if(params.iThumbnailSize == EListThumbnailSize)
+ {
+ params.iThumbnailSize = EVideoListThumbnailSize;
+ }
+ }
+ else if(aSourceType == TThumbnailPersistentSize::EAudio)
+ {
+ if(params.iThumbnailSize == EFullScreenThumbnailSize)
+ {
+ params.iThumbnailSize = EAudioFullScreenThumbnailSize;
+ }
+ else if(params.iThumbnailSize == EGridThumbnailSize)
+ {
+ params.iThumbnailSize = EAudioGridThumbnailSize;
+ }
+ else if(params.iThumbnailSize == EListThumbnailSize)
+ {
+ params.iThumbnailSize = EAudioListThumbnailSize;
+ }
+ }
+ }
+
+//------------------------------------------------------------------------
+// CThumbnailServerSession::ModifyThumbnailSize
+// ---------------------------------------------------------------------------
+//
+void CThumbnailServerSession::ResolveMimeTypeL( RFile64* aFile )
+ {
+ TThumbnailRequestParams& params = iRequestParams();
+ TInt res = 0;
+
+ // mime type
+ if ( params.iMimeType.Des8() == KNullDesC8 && !Server()->SupportedMimeType(params.iMimeType) )
+ {
+ // try parsing from file extension
+ res = Server()->MimeTypeFromFileExt( params.iFileName, params.iMimeType );
+ if ( res == KErrNotFound )
+ {
+ if( aFile )
+ {
+ // parsed type not in the list, resolve from file
+ params.iMimeType = Server()->ResolveMimeTypeL(*aFile);
+ }
+ else
+ {
+ Server()->Fs().ShareProtected();
+ RFile64 file;
+ CleanupClosePushL( file );
+
+ User::LeaveIfError( file.Open( Server()->Fs(), params.iFileName, EFileShareReadersOrWriters ));
+ TN_DEBUG2( "CThumbnailServerSession::ResolveMimeType - file handle opened for %S", ¶ms.iFileName );
+
+ params.iMimeType = Server()->ResolveMimeTypeL(file);
+
+ file.Close();
+ TN_DEBUG1("CThumbnailServerSession::ResolveMimeType - file handle closed");
+
+ CleanupStack::Pop( &file );
+ }
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// RThumbnailMessage::FilterSqlErr
+// ---------------------------------------------------------------------------
+//
+TInt CThumbnailServerSession::ConvertSqlErrToE32Err( TInt aReason )
+ {
+ TInt e32Err;
+ if ( aReason >= - 144 )
+ // magic: [-1..-144] is E32 error range
+ {
+ // E32 error value or non-negative value
+ e32Err = aReason;
+ }
+ else
+ {
+ switch ( aReason )
+ {
+ case KSqlErrGeneral:
+ e32Err = KErrGeneral;
+ break;
+ case KSqlErrInternal:
+ e32Err = KErrGeneral;
+ break;
+ case KSqlErrPermission:
+ e32Err = KErrPermissionDenied;
+ break;
+ case KSqlErrAbort:
+ e32Err = KErrAbort;
+ break;
+ case KSqlErrBusy:
+ e32Err = KErrServerBusy;
+ break;
+ case KSqlErrLocked:
+ e32Err = KErrLocked;
+ break;
+ case KSqlErrReadOnly:
+ e32Err = KErrAccessDenied;
+ break;
+ case KSqlErrInterrupt:
+ e32Err = KErrAbort;
+ break;
+ case KSqlErrIO:
+ e32Err = KErrGeneral;
+ break;
+ case KSqlErrCorrupt:
+ e32Err = KErrCorrupt;
+ break;
+ case KSqlErrNotFound:
+ e32Err = KErrNotFound;
+ break;
+ case KSqlErrFull:
+ e32Err = KErrOverflow;
+ break;
+ case KSqlErrCantOpen:
+ e32Err = KErrCouldNotConnect;
+ break;
+ case KSqlErrProtocol:
+ e32Err = KErrLocked;
+ break;
+ case KSqlErrEmpty:
+ e32Err = KErrNotFound;
+ break;
+ case KSqlErrSchema:
+ e32Err = KErrAbort;
+ break;
+ case KSqlErrTooBig:
+ e32Err = KErrTooBig;
+ break;
+ case KSqlErrConstraint:
+ e32Err = KErrGeneral;
+ break;
+ case KSqlErrMismatch:
+ e32Err = KErrGeneral;
+ break;
+ case KSqlErrMisuse:
+ e32Err = KErrGeneral;
+ break;
+ case KSqlErrRange:
+ e32Err = KErrOverflow;
+ break;
+ case KSqlErrNotDb:
+ e32Err = KErrCorrupt;
+ break;
+ case KSqlErrStmtExpired:
+ e32Err = KErrAbort;
+ break;
+ default:
+ e32Err = aReason;
+ }
+ }
+ return e32Err;
+ }
+
+// End of file