uigraphics/AknIcon/srvsrc/AknIconSrvSession.cpp
changeset 0 05e9090e2422
--- /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 <e32std.h>
+
+#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<TAknIconInitData> 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