diff -r 000000000000 -r 05e9090e2422 uigraphics/AknIcon/srvsrc/AknIconSrvSession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uigraphics/AknIcon/srvsrc/AknIconSrvSession.cpp Thu Dec 17 09:14:12 2009 +0200 @@ -0,0 +1,367 @@ +/* +* Copyright (c) 2002 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: Session to AknIconServer. +* +*/ + + + +// INCLUDE FILES + +#include + +#include "AknIconSrvSession.h" +#include "AknIconSrv.h" +#include "AknIconPanic.h" +#include "AknIconSrvIconItem.h" +#include "AknIconTraces.h" + + +// CONSTANTS + +const TInt KIconItemArrayGranularity = 4; +const TInt KPreservedItemArrayGranularity = 1; + +// ================= MEMBER FUNCTIONS ========================================== + +CAknIconSrvSession::CAknIconSrvSession() : + CSession2(), + iIconItems( KIconItemArrayGranularity ), + iPreservedItems( KPreservedItemArrayGranularity ), + iClientPanicCode(EBadServerRequest) + { + } + +CAknIconSrvSession::~CAknIconSrvSession() + { + // Cleanup all icons and preserved icon data items referred by the session + // that were not freed normally, for example due to a client thread panic. + + TInt count = iIconItems.Count(); + + for ( TInt i = 0 ; i < count ; i++ ) + { + Server()->CleanupSessionIconItem( iIconItems[i] ); + } + + count = iPreservedItems.Count(); + + for ( TInt j = 0 ; j < count ; j++ ) + { + Server()->CleanupSessionPreservedItem( iPreservedItems[j] ); + } + + iIconItems.Close(); + iPreservedItems.Close(); + } + +// ----------------------------------------------------------------------------- +// CAknIconSrvSession::DispatchMessageL() +// ----------------------------------------------------------------------------- + +TInt CAknIconSrvSession::DispatchMessageL( const RMessage2& aMessage ) + { +// Debug heap testing. +#ifdef _DEBUG + if ( iDbgHeapFailNextCount ) + { + __UHEAP_FAILNEXT( iDbgHeapFailNextCount ); + iDbgHeapFailNextCount++; + } +#endif // _DEBUG + + TInt ret = KErrNone; + + switch ( aMessage.Function() ) + { + case ERetrieveOrCreateSharedIcon: + { + // Append and remove a dummy element to prevent memory allocation + // failure when the real item is appended. + TAknIconSrvSessionIconItem dummy; + User::LeaveIfError( iIconItems.Append( dummy ) ); + iIconItems.Remove( iIconItems.Count() - 1 ); + + const CAknIconSrvIconItem* item = + Server()->RetrieveOrCreateSharedIconL(); + + TInt users = ( item->iMaskId < 0 ? 1 : 2 ); + + // Append in here cannot fail now because of the operation done above. + ModifyUserCount( item, users ); // bitmap and optionally mask + break; + } + + case EFreeBitmap: + { + const CAknIconSrvIconItem* item = Server()->FreeBitmapL(); + ModifyUserCount( item, -1 ); + break; + } + + case EGetContentDimensions: + { + Server()->GetContentDimensionsL(); + break; + } + + case EPreserveIconData: + { + // Append and remove a dummy element to prevent memory allocation + // failure when the real item is appended. + TAknIconSrvSessionPreservedItem dummy; + User::LeaveIfError( iPreservedItems.Append( dummy ) ); + iPreservedItems.Remove( iPreservedItems.Count() - 1 ); + + const CAknIconDataItem* item = Server()->PreserveIconDataL(); + ModifyUserCount( item, 1 ); + break; + } + + case EDestroyIconData: + { + const CAknIconDataItem* item = Server()->UnpreserveIconDataL(); + ModifyUserCount( item, -1 ); + break; + } + + case EGetInitData: + { + TAknIconInitData data; + Server()->GetInitData( data ); + TPckgC retPack( data ); + aMessage.WriteL( 0, retPack ); + break; + } + + case EAknIconServRequestEnableCache: + { + if (aMessage.HasCapability(ECapabilityWriteDeviceData)) + Server()->EnableCache( aMessage.Int0() ); + else + ret = KErrPermissionDenied; + break; + } + +// Debug heap testing. +#ifdef _DEBUG + case EServerHeapMark: + { + __UHEAP_MARK; + break; + } + + case EServerHeapMarkEnd: + { + __UHEAP_MARKEND; + break; + } + + case EServerHeapFailNext: + { + iDbgHeapFailNextCount = 0; + __UHEAP_FAILNEXT( aMessage.Int0() ); + break; + } + + case EServerHeapFailNextIncreasing: + { + iDbgHeapFailNextCount = aMessage.Int0(); + break; + } + + case EServerHeapReset: + { + iDbgHeapFailNextCount = 0; + __UHEAP_RESET; + break; + } + + case EServerResetDynamicallyChangingAllocations: + { + Server()->ResetDynamicallyChangingAllocations(); + break; + } + + case EServerHeapUsed: + { + TInt heapUsed; + User::AllocSize( heapUsed ); + ret = heapUsed; + break; + } + + case EServerSetPreferredIconDisplayMode: + { + Server()->SetPreferredIconDisplayMode( (TDisplayMode)aMessage.Int0() ); + break; + } + +#endif // _DEBUG + + default: + { + // PanicClient( aMessage, EBadServerRequest ); + // If we dont call Leave here, Server crashes.. + // Fixed it as a part of error fix JJUN-78QCL6 + User::Leave(KAknIconSrvCodePanicClient); + break; + } + } + + return ret; + } + +// ----------------------------------------------------------------------------- +// CAknIconSrvSession::ServiceL() +// ----------------------------------------------------------------------------- + +void CAknIconSrvSession::ServiceL(const RMessage2& aMessage) + { + TInt ret = KErrNone; + + TInt opCode = aMessage.Function(); + + // File handles are transfered to server side with these opCodes. + if ( opCode == ERetrieveOrCreateSharedIcon || + opCode == EGetContentDimensions || + opCode == EPreserveIconData ) + { + if ( aMessage.Int2() ) + { + User::LeaveIfError( + iAdoptedFile.AdoptFromClient( aMessage, 2, 3 ) ); + } + } + + TRAPD( err, + { + ret = DispatchMessageL( aMessage ); + } ); + + iAdoptedFile.Close(); + +#ifdef __AKNICON_TRACES + if (err != KErrNone) + { + RDebug::Print( _L("CAknIconSrvSession: %x DispatchMessageL leaved: %d"), this, err ); + } +#endif + + // Don't complete message if client panicked + if (err != KAknIconSrvCodePanicClient) + { + // If the service routine leaved, return the leave reason. + // Otherwise, return its return code. + + aMessage.Complete( err != KErrNone ? err : ret ); + } + else + { + if (aMessage.IsNull() == EFalse) + { + PanicClient( aMessage, iClientPanicCode ); + } + User::Leave(KAknIconSrvCodePanicClient); + } + } + +// ----------------------------------------------------------------------------- +// CAknIconSrvSession::PanicClient() +// ----------------------------------------------------------------------------- + +void CAknIconSrvSession::PanicClient( const RMessage2& aMessage, TAknIconPanic aPanic ) const + { + aMessage.Panic( KAknIconPanicCategory, aPanic ); + } + +// ----------------------------------------------------------------------------- +// CAknIconSrvSession::ModifyUserCount() +// ----------------------------------------------------------------------------- +// +void CAknIconSrvSession::ModifyUserCount( + const CAknIconSrvIconItem* aItem, + TInt aCount ) + { + TAknIconSrvSessionIconItem newItem = { aItem, aCount }; + TInt index = iIconItems.FindInOrder( + newItem, TAknIconSrvSessionIconItem::LinearOrder ); + + if ( index >= 0 ) + { + TAknIconSrvSessionIconItem& sessionItem = iIconItems[index]; + // session's user count for this icon + sessionItem.iUserCount += aCount; + + if ( sessionItem.iUserCount == 0 ) + { + iIconItems.Remove( index ); + } + return; + } + + // If not found, it must be a new item, + // and then the user count should be increasing. + __ASSERT_ALWAYS( aCount > 0, User::Invariant() ); + + // Cannot fail at this stage, see caller function. + iIconItems.InsertInOrder(newItem, TAknIconSrvSessionIconItem::LinearOrder ); + } + +// ----------------------------------------------------------------------------- +// CAknIconSrvSession::ModifyUserCount() +// ----------------------------------------------------------------------------- +// +void CAknIconSrvSession::ModifyUserCount( + const CAknIconDataItem* aItem, + TInt aCount ) + { + TInt count = iPreservedItems.Count(); + + for ( TInt i = 0 ; i < count ; i++ ) + { + TAknIconSrvSessionPreservedItem& sessionItem = iPreservedItems[i]; + if ( sessionItem.iDataItem == aItem ) + { + // session's user count for this icon + sessionItem.iUserCount += aCount; + + if ( sessionItem.iUserCount == 0 ) + { + iPreservedItems.Remove( i ); + } + return; + } + } + + // If not found, it must be a new item, + // and then the user count should be increasing. + __ASSERT_ALWAYS( aCount > 0, User::Invariant() ); + + TAknIconSrvSessionPreservedItem newItem = { aItem, aCount }; + // Cannot fail at this stage, see caller function. + iPreservedItems.Append( newItem ); + } + +// ----------------------------------------------------------------------------- +// CAknIconSrvSession::AdoptedFileHandle() +// ----------------------------------------------------------------------------- +// +RFile& CAknIconSrvSession::AdoptedFileHandle() + { + return iAdoptedFile; + } + + +// End of File