diff -r 000000000000 -r 2014ca87e772 imagehandlingutilities/thumbnailmanager/thumbnailserver/src/thumbnailserversession.cpp --- /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 + +#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