/*
* Copyright (c) 2006 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 session
*
*/


#include <flogger.h>
#include "alfappsrvsession.h"
#include "alf/alfappserver.h"
#include "alf/alfappui.h"
#include "alf/alfconstants.h"
#include "alf/alfclientwindow.h"
#include "alfsrvdisplaysubsession.h"
#include "alfsrvcontrolgroupsubsession.h"
#include "alfsrvsettingshandler.h"
#include "alfsrvtranseffect.h"
#include "alf/alfsrveffectenv.h"
#include "alf/alfserverutils.h"
#include "alflogger.h"
#include "alfclientserver.h"
#include "alfsrvtexturemanager.h"
#include "alfsrvscreenbuffermanager.h"
#include "alfstreamerconsts.h"
#include "alfdecoderserverclient.h"



#include <coemain.h>

#include <alf/alfroster.h>
#include <alf/alftexture.h>

#include <uiacceltk/HuiControl.h>
#include <uiacceltk/HuiControlGroup.h>
#include <uiacceltk/HuiDisplay.h>
#include <uiacceltk/HuiDisplayCoeControl.h>
#include <uiacceltk/HuiEnv.h>
#include <uiacceltk/HuiTextVisual.h>
#include <uiacceltk/HuiTransformation.h>
#include <uiacceltk/HuiBorderBrush.h>
#include <uiacceltk/HuiImageVisual.h>
#include <uiacceltk/HuiGridLayout.h>
#include <uiacceltk/HuiTextureProcessor.h>
#include <uiacceltk/HuiSegmentedTexture.h>
#include <uiacceltk/huitextstylemanager.h>
#include <uiacceltk/huitextstyle.h>
#include <uiacceltk/HuiFont.h>
#include <uiacceltk/HuiTexture.h>
#include <uiacceltk/HuiUtil.h>

_LIT( KAlfFPSLogDir, "alf"); // remember to create the c:\logs\alf in order to enable logging
_LIT( KAlfFPSLogFile, "alffpslog.txt");
    

const TReal32 KAlfUseDefaultFrameRate = 0.f;

/**
 * If estimated memory consumption is larger than this constant,
 * then ALF will do additional steps to ensure that texture loading succeeds.
 * However, client is still responsible of requesting sufficient memory from GOOM.
 */
const TInt KAlfReleaseMemoryThresholdInBytes = 3000000;

TBool RealCompare( 
    TReal32 aCompare1, 
    TReal32 aCompare2, 
    TReal32 aEpsilon = 0.001f  )
    {
    if ( Abs(aCompare1 - aCompare2) < aEpsilon )
        {
        return ETrue;
        }
    return EFalse;
    }

/**
 * Size of command batch buffer allocated from stack.
 * (This is used if all else fails)
 */
const TInt KAlfStackBatchBufferSize = 128;

// bitmap provider

NONSHARABLE_CLASS(CSharedBitmapProvider) : public CBase, public MHuiBitmapProvider
	{
public:
	CSharedBitmapProvider();
	CSharedBitmapProvider(TInt aBitmapHandle, TInt aMaskHandle);
	~CSharedBitmapProvider();
	// from MHuiBitmapProvider	
	void ProvideBitmapL(TInt aId, CFbsBitmap*& aBitmap, CFbsBitmap*& aMaskBitmap);				
private:
	TInt iBitmapHandle;
	TInt iMaskHandle;
	};

CSharedBitmapProvider::CSharedBitmapProvider()
	{
		
	}

CSharedBitmapProvider::CSharedBitmapProvider(TInt aBitmapHandle, TInt aMaskHandle)
	{
	iBitmapHandle = aBitmapHandle;
	iMaskHandle = aMaskHandle;	
	}

CSharedBitmapProvider::~CSharedBitmapProvider()
	{
	}

void CSharedBitmapProvider::ProvideBitmapL(TInt /*aId*/, CFbsBitmap*& aBitmap, CFbsBitmap*& aBitmapMask)
	{
	CFbsBitmap* bitmap(0);
	CFbsBitmap* mask(0);
	
	if (iBitmapHandle) // mandatory
	    {
	    bitmap = new (ELeave) CFbsBitmap;
	    CleanupStack::PushL(bitmap);
	    bitmap->Reset();
	    User::LeaveIfError(bitmap->Duplicate(iBitmapHandle));
	    }
	else
	    {
	    User::Leave(KErrArgument);
	    }
	       
	if ( iMaskHandle ) // optional
	    {
     	mask = new (ELeave) CFbsBitmap;
	    CleanupStack::PushL(mask);
	    mask->Reset();
	    User::LeaveIfError(mask->Duplicate(iMaskHandle));
	    CleanupStack::Pop(); // mask
	    }
	
    CleanupStack::Pop(); // bitmap
    aBitmapMask = mask; 	
    aBitmap = bitmap; 	
    }



// ======== MEMBER FUNCTIONS ========

// ---------------------------------------------------------------------------
// Constructor
// ---------------------------------------------------------------------------
//
CAlfAppSrvSession::CAlfAppSrvSession(const CAlfAppServer* aServer)
    : CAlfAppSrvSessionBase(aServer),
      iExecutionFlags( 
        EAlfExecuteUsingDynamicBuffer + EAlfExecuteUsingCommonBuffer )
    {
    }

CAlfAppSrvSession* CAlfAppSrvSession::NewL(const CAlfAppServer* aServer)
    {
    CAlfAppSrvSession* me = new (ELeave) CAlfAppSrvSession(aServer);
    CleanupStack::PushL(me);
    me->ConstructL();
    CleanupStack::Pop();
    return me;
    }

void CAlfAppSrvSession::ConstructL()
    {
    BaseConstructL();
    
    AlfServer()->SetWindowChangeObserverL(this, TInt(this)); 
    
    iRefreshMode = EHuiRefreshModeAutomatic;
    iMaxFrameRate = KAlfUseDefaultFrameRate;
    iIdleThreshold = 10 * 1000; // 10 from HuiEnv as seconds
    iEffectEnv = CAlfSrvEffectEnv::NewL(*this);
    }

// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
//
CAlfAppSrvSession::~CAlfAppSrvSession()
    {
    iOwnershipItems.ResetAndDestroy();    
    
    if ( iTextureOwnedIdSet )
        {
        CAlfSrvTextureManager& manager = AlfTextureManager();
        TProcessId ownerId = TextureOwnerId();
        manager.DestroyDeletedTextureIds( ownerId );
        manager.RemoveClient( *this );
        }
    iTextures.ResetAndDestroy();        
    iAnimatedTextures.ResetAndDestroy();
    
    delete iEffectEnv;
    iEffectEnv = NULL;
    
    iTextureInfo.Close();
    
    iControlGroupOrder.Close();
    }


TRect CAlfAppSrvSession::ClientDrawingArea() const
    {
    return iClientDisplayRect;
    }
    
void CAlfAppSrvSession::SetClientDrawingArea( const TRect& aRect )
    {
    TRAP_IGNORE(SetClientDrawingAreaL(aRect))
    }

void CAlfAppSrvSession::SetClientDrawingAreaL( const TRect& aRect )
    {
    iClientDisplayRect = aRect;
    
    // Update all the control groups
    RPointerArray<CAlfSrvSubSessionBase> groups;
    CleanupClosePushL( groups );
    GetSubsessionsByTypeL( groups, EHuiObjectTypeControlGroup );
    for ( TInt g = 0 ; g < groups.Count() ; g++ )
        {
        CHuiControlGroup* group = groups[g]->AsHuiControlCroup();
        ASSERT( group ); 
        CHuiLayout* hostContainer = group->Control(0).ContainerLayout( NULL );
        
        hostContainer->SetSize( iClientDisplayRect.Size() );
        hostContainer->SetPos( iClientDisplayRect.iTl );
        }
    CleanupStack::PopAndDestroy( &groups ); // groups.Close()
    }
    
// ---------------------------------------------------------------------------
// From class CAlfAppSrvSessionBase.
// Called when client receives focus.
// ---------------------------------------------------------------------------
//   
void CAlfAppSrvSession::FocusGainedL( TBool /*aDoTransitionEffect*/ )
    {
    iFocused = ETrue;
    DeliverTextureInfo();
    
    // update frame rate
    if ( RealCompare( iMaxFrameRate, KAlfUseDefaultFrameRate ) )
        {
        SharedHuiEnv()->SetMaxFrameRate( 
            TReal32(AlfAppUi()->SettingsHandler().DefaultFramerate()) );
        }
    else
        {
        SharedHuiEnv()->SetMaxFrameRate( iMaxFrameRate );
        }
    
    // update refresh mode
    if ( SharedHuiEnv()->RefreshMode() != iRefreshMode )
        {
        SharedHuiEnv()->SetRefreshMode( iRefreshMode );
        }

    // update idle threshold
    SharedHuiEnv()->SetIdleThreshold( iIdleThreshold );
    
    // update display attributes for each display
    CHuiDisplay* display = NULL;
    RPointerArray<CAlfSrvSubSessionBase> displays;
    CleanupClosePushL( displays );
    GetSubsessionsByTypeL( displays, EHuiObjectTypeDisplay );
    for ( TInt d = 0 ; d < displays.Count() ; d++ )
        {
        CAlfSrvDisplaySubSession* displaySubSession = 
                static_cast<CAlfSrvDisplaySubSession*>( displays[d] );     
        displaySubSession->SetSessionFocused();
        if ( !display && !displaySubSession->IsTvOut())
            {
            display = &displaySubSession->Display();
            }
        }     
    CleanupStack::PopAndDestroy( &displays ); // displays.Close()
    
    if ( !display )
        {
        return;
        }
    
    // Enable animated textures for the session
    for (TInt index = 0; index < iAnimatedTextures.Count(); index++)
        {
       	iAnimatedTextures.operator[](index)->EnableAnimation(ETrue);     
        }

	// This is needed for Huitk BitBlit() to succeed 
    
#ifdef SYMBIAN_BUILD_GCE
    SharedHuiEnv()->ContinueRefresh();
#else
    AlfAppUi()->Container()->DrawNow();
#endif
    }
    
// ---------------------------------------------------------------------------
// From class CAlfAppSrvSessionBase.
// Called when client loses focus.
// ---------------------------------------------------------------------------
//
TBool CAlfAppSrvSession::FocusLostL( TBool /*aDoTransitionEffect*/ )
    {
    iFocused = EFalse;

    TBool didTransition = EFalse;
    
    if ( !SharedHuiEnv()->DisplayCount() )
        {
        return EFalse;
        }

    // Notify displays about losing focus so that tv out can be released
    CHuiDisplay* display = NULL;
    RPointerArray<CAlfSrvSubSessionBase> displays;
    CleanupClosePushL( displays );
    GetSubsessionsByTypeL( displays, EHuiObjectTypeDisplay );
    for ( TInt d = 0 ; d < displays.Count() ; d++ )
        {
        CAlfSrvDisplaySubSession* displaySubSession = 
                static_cast<CAlfSrvDisplaySubSession*>( displays[d] );     
        displaySubSession->SetSessionFocused(EFalse);
        if ( !display && !displaySubSession->IsTvOut())
            {
            display = &displaySubSession->Display();
            }
            
        }     
    CleanupStack::PopAndDestroy( &displays ); // displays.Close()

    if ( !display )
        {
        return didTransition;
        }

    if (display->DisplayType() != CHuiDisplay::EDisplayOffScreenBuffer) 
    	{
    	// Disable all animated textures for the session
    	for (TInt index = 0; index < iAnimatedTextures.Count(); index++)
        	{
      		iAnimatedTextures.operator[](index)->EnableAnimation(EFalse); 
        	}
#ifndef SYMBIAN_BUILD_GCE       	
      	StoreControlGroupOrderL(*display, EFalse ); // do not hide  
#endif
      	// background must be drawn as long as the effect is displayed 
       	// as the background will be visible if the effect does not cover full screen
       	// or is partially transparent.
    	}
    
    return didTransition;
    }

void CAlfAppSrvSession::StoreControlGroupOrderL(CHuiDisplay& aDisplay, TBool aAlsoHide )
    {
    for ( TInt g = 0 ; g < aDisplay.Roster().Count() ; g++ )
        {
        // first append the bottom one
        CHuiControlGroup& group = aDisplay.Roster().ControlGroup( g );
        
        // make sure we only store control groups for this session
        if ( GetHandleFromInterface(EHuiObjectTypeControlGroup, &group) != KErrNotFound )
            {
            iControlGroupOrder.AppendL( &group );
            }
        }
    
    // at the end the lowest index the bottom most and the biggest index the top most.
    
    // hide at the end so it does not affect the order of the group in the roster
    if ( aAlsoHide )
        {
        for ( TInt i = 0 ; i < iControlGroupOrder.Count() ; i++ )
            {
            CHuiLayout* hostContainer = iControlGroupOrder[i]->Control(0).ContainerLayout( NULL );

            aDisplay.Roster().Hide( *iControlGroupOrder[i] );
            }
        }
    }
    
void CAlfAppSrvSession::ShowControlGroupsInOrderL(CHuiDisplay& /*aDisplay*/)
    {
/*#ifdef SYMBIAN_BUILD_GCE
    iControlGroupOrder.Reset();
    // gather all the control groups that belong to this session
    for ( TInt g = 0 ; g < aDisplay.Roster().Count() ; g++ )
        {
        // first append the bottom one
        CHuiControlGroup& group = aDisplay.Roster().ControlGroup( g );
        
        // make sure we only store control groups for this session
        if ( GetHandleFromInterface(EHuiObjectTypeControlGroup, &group) != KErrNotFound )
            {
            iControlGroupOrder.AppendL( &group );
            }
        }
#endif
    // put this session's controlgroups on top
    while ( iControlGroupOrder.Count() )
        {
        CHuiControlGroup& group = *iControlGroupOrder[iControlGroupOrder.Count()-1];
        
        // make sure that the group still exists.
        if ( GetHandleFromInterface(EHuiObjectTypeControlGroup, &group) != KErrNotFound )
            {
            CHuiLayout* hostContainer = group.Control(0).ContainerLayout( NULL );

#ifdef SYMBIAN_BUILD_GCE
            
            AlfAppUi()->ShowControlGroupL(aDisplay.Roster(), group, KHuiRosterShowAtTop, 0); 
            
#else    
            aDisplay.Roster().ShowL( group, KAlfRosterShowAtBottom );
#endif
            iControlGroupOrder.Remove(iControlGroupOrder.Count()-1);
            }
        }
    iControlGroupOrder.Reset();*/
    }
    
void CAlfAppSrvSession::ReOrderControlGroupSessionsL( RPointerArray<CAlfSrvSubSessionBase>& aGroupSessions )
    {
    if ( iControlGroupOrder.Count() && aGroupSessions.Count() > 1 )
        {
        // go through the items from bottom to top
        for ( TInt g = iControlGroupOrder.Count() -1 ; g >= 0 ; g-- ) 
            {
            CHuiControlGroup* nextGroupFromBottom = iControlGroupOrder[g];
            
            // Find the session and move it into first position
            for ( TInt s = 0 ; s < aGroupSessions.Count() ; s++ )
                {
                CAlfSrvControlGroupSubSession* controlGroupSubSession = static_cast<CAlfSrvControlGroupSubSession*>( aGroupSessions[s] );   
                if ( &controlGroupSubSession->ControlGroup() == nextGroupFromBottom )
                    {
                    // move into g:th position
                    aGroupSessions.Remove( s );
                    User::LeaveIfError( aGroupSessions.Insert( controlGroupSubSession, 0 ) );
                    }
                }
            }
        }
    }

void CAlfAppSrvSession::SetBackgroundMaxFps( TBool aBackground )
    {
    
    TReal32 newMaxFrameRate = 0;
    
    // update frame rate
    if ( RealCompare( iMaxFrameRate, KAlfUseDefaultFrameRate ) )
        {
        newMaxFrameRate = TReal32( AlfAppUi()->SettingsHandler().DefaultFramerate() );
        SharedHuiEnv()->SetMaxFrameRate( 
            TReal32(AlfAppUi()->SettingsHandler().DefaultFramerate()) );
        }
    else
        {
        newMaxFrameRate = iMaxFrameRate;
        }    
    
    if( aBackground )
        {  
        newMaxFrameRate /= 2;
        }
    SharedHuiEnv()->SetMaxFrameRate( newMaxFrameRate );
    }


// ---------------------------------------------------------------------------
// Is client application focused?
// ---------------------------------------------------------------------------
//    
TBool CAlfAppSrvSession::IsFocused() const
    {
    return iFocused;
    }
    
    
// ---------------------------------------------------------------------------
// From class MWindowVisibilityObserver.
// Called when window becomes fully visible.
// ---------------------------------------------------------------------------
//
void CAlfAppSrvSession::WindowFullyVisible()
    {
    iPartiallyVisible = ETrue;
    DeliverTextureInfo();
    }
   
// ---------------------------------------------------------------------------
// From class MWindowVisibilityObserver.
// Called when window becomes partially visible.
// ---------------------------------------------------------------------------
// 
void CAlfAppSrvSession::WindowPartiallyVisible()
    {
    iPartiallyVisible = ETrue;
    DeliverTextureInfo();
    }
    
// ---------------------------------------------------------------------------
// From class MWindowVisibilityObserver.
// Called when window becomes fully invisible.
// ---------------------------------------------------------------------------
//
void CAlfAppSrvSession::WindowNotVisible()
    {
    // already not shown...
    if ( !iPartiallyVisible )
        {
        return;
        }
    iPartiallyVisible = EFalse;
    }

// ---------------------------------------------------------------------------
// From class MWindowVisibilityObserver.
// Returns window-owning control.
// ---------------------------------------------------------------------------
//
CCoeControl* CAlfAppSrvSession::CoeControl()
    {
    return NULL;//iCoeDisplay;
    }

CAlfAppServer::TAlfWGPostion CAlfAppSrvSession::PreferredWindowGroupPosition() const
    {
    if ( iUsesFullScreen )
        {
        return CAlfAppServer::EOnTopOfParent;
        }
    else
        {
        return CAlfAppServer::EBehindOfParent;
        }
    }
    
THuiRefreshMode CAlfAppSrvSession::PreferredRefreshMode() const
    {
    return iRefreshMode;
    }


// ---------------------------------------------------------------------------
// From class CAlfAppSrvSessionBase.
// Called when a message is received from the client.
// ---------------------------------------------------------------------------
//
void CAlfAppSrvSession::DoHandleCommandL(const RMessage2& aMessage)
    {
    switch( aMessage.Function() )
        {
        case EAlfQtCommandBuffer:
            {
            PostQtCommandBufferL( aMessage );
            break;
            }
        
		case EAlfEnvSetRefreshMode:
            {
            EnvSetRefreshModeL( aMessage );
            break;    
            }
            
        case EAlfEnvSetMaxFrameRate:
            {
            EnvSetMaxFrameRateL( aMessage );
            break;
            }
            
        case EAlfEnvContinueRefresh:
            {
            EnvContinueRefreshL( aMessage );
            break;
            }
            
        case EAlfEnvPauseRefresh:
            {
            EnvPauseRefreshL( aMessage );
            break;
            }
            
        case EAlfEnvRefreshCallBack:
            {
            EnvRefreshCallBackL( aMessage );
            break;
            }
            
        case EAlfEnvRenderer:
            {
            EnvRendererL( aMessage );
            break;
            }
        case EAlfEnvSetIdleThreshold:
            {
            EnvSetIdleThresholdL( aMessage );
            break;
            }
            
        case EAlfRosterShow:
            {
            
            // Parse parameters
            // 0: control group handle (in)
            const TInt cntrlGroupHandle = aMessage.Int0();
            CAlfSrvSubSessionBase& subSession1 = SubSession( cntrlGroupHandle );
            CAlfSrvControlGroupSubSession& controlGroupSubSession = 
                static_cast<CAlfSrvControlGroupSubSession&>(subSession1);
            CHuiControlGroup& controlGroup = controlGroupSubSession.ControlGroup();
                
            // 1: where (in)
            const TInt where = aMessage.Int1();
            // 2: display handle (in)
            const TInt displayHandle = aMessage.Int2();
            CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle );
            CAlfSrvDisplaySubSession& displaySubSession = 
                static_cast<CAlfSrvDisplaySubSession&>(subSession2);
            CHuiDisplay& display = displaySubSession.Display();

            controlGroupSubSession.SetIsShown( ETrue );
            controlGroupSubSession.PreferredPos() = where;
            
            // Show only if session is focused, otherwise delay until focus is gained
            if (iFocused)
                {
#ifdef SYMBIAN_BUILD_GCE
                CHuiLayout* hostContainer = controlGroup.Control(0).ContainerLayout( NULL );                
                if(hostContainer)
                    hostContainer->ClearFlags( EHuiVisualFlagUnderOpaqueHint);
                AlfAppUi()->ShowControlGroupL(display.Roster(), controlGroup, where, 0);
#else    
                display.Roster().ShowL(controlGroup, where);                                    
#endif
                AlfServer()->AdjustWindowGroupPositionL( 
                    *CHuiStatic::RootWin(), 
                    ClientWindowGroup(), 
                    PreferredWindowGroupPosition()  );
                }
            else
                {
#ifdef SYMBIAN_BUILD_GCE
            CHuiLayout* hostContainer = controlGroup.Control(0).ContainerLayout( NULL );                
                if(hostContainer)
                    hostContainer->ClearFlags(EHuiVisualFlagUnderOpaqueHint);
                AlfAppUi()->ShowControlGroupL(display.Roster(), controlGroup, where, 0);
#else                    

                if (where == KHuiRosterShowAtTop)
                    {
                    if (iControlGroupOrder.Count())
                        {
                        iControlGroupOrder.InsertL(&controlGroup, 0);            
                        }
                    else
                        {
                        iControlGroupOrder.AppendL(&controlGroup);                
                        }    
                    }
                else if (where == KHuiRosterShowAtBottom)
                    {
                
                    iControlGroupOrder.AppendL(&controlGroup);                
                    }
                else
                    {
                    if (iControlGroupOrder.Count() < where)
                        {
                        iControlGroupOrder.AppendL(&controlGroup);                        
                        }
                    else
                        {
                        iControlGroupOrder.InsertL(&controlGroup, where);                                        
                        }                                                
                    }
#endif                    
                }    
                        
            break;
            }
            
        case EAlfRosterHide:
            {
            RosterHideL(aMessage);
            break;
            }
            
        case EAlfRosterShowVisual:
            {
            RosterShowVisualL(aMessage);
            break;
            }
            
        case EAlfRosterHideVisual:
            {
            RosterHideVisualL(aMessage);
            break;
            }
        case EAlfRosterMoveVisualToFront:
            {
            RosterMoveVisualToFrontL(aMessage);
            break;
            }
        case EAlfRosterSetPointerEventFlags:
            {
            RosterSetPointerEventFlagsL(aMessage);
            break;
            }
        case EAlfRosterAddPointerEventObserver:
            {
            RosterAddPointerEventObserverL(aMessage);
            break;
            }
        case EAlfRosterRemovePointerEventObserver:
            {
            RosterRemovePointerEventObserverL(aMessage);
            break;
            }
        case EAlfRosterSetPointerDragTreshold:
            {
            RosterSetPointerDragTresholdL(aMessage);
            break;
            }
        case EAlfRosterDisableLongTapEventsWhenDragging:
            {
            RosterDisableLongTapEventWhenDraggingL(aMessage);
            break;
            }
        case EAlfTextureStopAnimation:
            {
            if ( RequireTextureOwnerId( aMessage ) )
                {
                TextureStopAnimation(aMessage);
                }
            break;
            }
        case EAlfTextureCleanAnimation:
            {
            if ( RequireTextureOwnerId( aMessage ) )
                {
                TextureCleanAnimation(aMessage);
                }
            break;
            }    
        case EAlfTextureStartAnimation:
            {
            if ( RequireTextureOwnerId( aMessage ) )
                {
                TextureStartAnimation(aMessage);
                }
            break;
            }
        case EAlfTextureCreateAnimated:
            {
            if ( RequireTextureOwnerId( aMessage ) )
                {
                TextureCreateAnimatedL(aMessage);
                }
            break;
            }
        case EAlfTextureCreate:
            {
            if ( RequireTextureOwnerId( aMessage ) )
                {
                TextureCreateL(aMessage);
                }
            break;
            }
             
        case EAlfTextureUnload:
            {
            if ( RequireTextureOwnerId( aMessage ) )
                {
                TextureUnload(aMessage);
                }
            break;
            }
        case EAlfTextureDelete:
            {
            if ( RequireTextureOwnerId( aMessage ) )
                {
                TextureDelete(aMessage);
                }
            break;
            }
        case EAlfTextureRelease:
            {
            if ( RequireTextureOwnerId( aMessage ) )
                {
                TextureRelease(aMessage);
                }
            break;
            }
        case EAlfTextureRestore:
            {
            if ( RequireTextureOwnerId( aMessage ) )
                {
                TextureRestore(aMessage);
                }
            break;
            }
        case EAlfTextureNotifySkinChanged:
            {
        	if ( RequireTextureOwnerId( aMessage ) )
        	    {
        	    TextureNotifySkinChanged(aMessage);
        	    }
            break;
            }             
        case EAlfTextureLoad:
            {
            if ( RequireTextureOwnerId( aMessage ) )
                {
                TextureLoadL(aMessage);
                }
            break;
            } 
        case EAlfTextureBlur:
            {
            if ( RequireTextureOwnerId( aMessage ) )
                {
                TextureBlurL(aMessage);
                }
            break;
            } 
        case EAlfTextureHasContent:
            {
            if ( RequireTextureOwnerId( aMessage ) )
                {
                TextureHasContentL(aMessage);
                }
            break;
            } 
        case EAlfTextureUpdateOwnerId:
            {
            UpdateTextureOwnerIdL( aMessage );    
            break;
            }
        case EAlfTextureSetAutoSizeParams:
            {
            if ( RequireTextureOwnerId( aMessage ) )
                {
                TextureSetAutoSizeParamsL( aMessage );    
                }
            break;
            }
            
            
        case EAlfNotifyAppVisibility:
            {
            TBool foreground = aMessage.Int0();
          	if (ClientWindowGroup() != KErrNotFound) // if Alf client have not set wg, treat it like non-Alf app 
          		{	
            	if ( foreground )
                	{         	
#ifdef SYMBIAN_BUILD_GCE
                	ActivateContainerLayoutL(ETrue);         	
#endif
                	AlfServer()->FocusedWindowGroupChangedL( this );
                	AlfServer()->AppUi()->UpdateActiveSession(this);
                
                	// Make sure that Env will refresh the screen 
                	// when we gain focus
                	AlfServer()->AppUi()->HuiEnv().ContinueRefresh();          			
                	}
            	else
                	{
                	// check if there is some other alf application on top of this one and set
                	// that application's session as a activesession
                	CAlfAppSrvSessionBase* newFocusSession = AlfServer()->UpMostClientAboveWg( ClientWindowGroup() );
 
            	    if( newFocusSession )
            	        {
                        AlfServer()->FocusedWindowGroupChangedL( newFocusSession );
            	        }
            	    else
            	        {
            	        // do the "event window" repositioning immediately
            	        AlfServer()->FocusedWindowGroupChangedL( NULL );
            	        }
            	    
            	    AlfServer()->AppUi()->UpdateActiveSession( newFocusSession );

                    // The following line removes the flickering (=drawing and empty frame)
                    // when non-alfred application is exited to appshell.
#ifndef SYMBIAN_BUILD_GCE
                	AlfServer()->AppUi()->Container()->DrawDeferred();
#endif
                	}    
          		}
            break;
            }
            
        case EAlfGetPointerEvent:
            {
            TriggerPointerEvent(&aMessage);
            return; // don't complete message here
            }
    
        case EAlfCancelPtrEvents:
            {
            CancelPointerEvents();
            break;
            }

        case EAlfGetSystemEvent:
            {
            GetSystemEvents(&aMessage);
            return; // don't complete message here
            }
    
        case EAlfCancelSystemEvents:
            {
            CancelSystemEvents();
            break;
            }
            
        case ESetFullScreenDrawing:
            {
            iUsesFullScreen = aMessage.Int0();
            break;
            }
        case EAlfLayoutMetricsTextStyleData:
            {
        	LayoutMetricsTextStyleDataL(aMessage);
            break;
            } 

        case EAlfSetWgParent:
            {
            SetParentWindowGroupId(aMessage.Int0());
            break;
            }
        case EAlfSBufAddObserver:
            {
            AlfServer()->ScreenBufferManager().AddScreenBufferObserver(this, aMessage);
            return; // message is completed in the method above
            } 
        case EAlfSBufRemoveObserver:
            {
            AlfServer()->ScreenBufferManager().RemoveScreenBufferObserver(this, aMessage);
            break;
            } 
        case EAlfSBufRequestNextBuffer:
            {
            AlfServer()->ScreenBufferManager().RequestNextBuffer(this, aMessage);
            return; // message is completed in the method above
            } 
        case EAlfSBufRequestBufferDraw:
            {
            AlfServer()->ScreenBufferManager().RequestBufferDraw(this, aMessage);
            return; // message is completed in the method above
            } 
        case EAlfSBufRequestEvent:
            {
            AlfServer()->ScreenBufferManager().RequestScreenBufferEvent(this, aMessage);
            return; // don't complete message here
            }          
            
        case EAlfDoSubSessionBatchCmd:
            {
            ExecuteBatchCommandsL(aMessage);
            break;
            }   
      
        case EAlfConfigureBatchCmd:
            {
            ConfigureBatchCommandExecutionL( aMessage );
            break;
            }

        case EAlfNotifyTextureInfo:
            {           
            NotifyTextureInfo( aMessage );            
            }
            return;
            
        case EAlfCancelNotifyTextureInfo:
            {
            if ( !iTextureInfoEvent.IsNull() )
                {
                iTextureInfoEvent.Complete( KErrCancel );
                }
            }
            break;
        case EAlfDirectClientFPSCounterOn:
            {
            ReportFrameRateBegin( aMessage );
            break;
            }
        case EAlfDirectClientFPSCounterOff:
            {
            ReportFrameRateEnd( aMessage );
            break;
            }
        case EAlfEnableLowMemoryState:
            {
            EnvEnableLowMemoryState( aMessage );
            break;
            }    
            
        case EAlfForceSwRendering:
            {
            EnvForceSwRendering( aMessage );
            break;    
            }
        
        case EAlfGetSizeAndRotation:
            {
            EnvGetSizeAndRotation( aMessage );
            break;
            }
            
        case EAlfReadPixels:
            {
            EnvReadPixels( aMessage );
            break;
            }
                        
        case EAlfBlankScreen:
            {
            AlfAppUi()->DoBlankScreen(aMessage);
            break;    
            }
            
            
        default:
            User::Leave( KErrNotSupported );
        }

    if ( !aMessage.IsNull() )
        {
        aMessage.Complete( KErrNone );
        }
    }
  
// ---------------------------------------------------------------------------
// class    :   CHuiEnv
// function :   SetRefreshMode
// param 0  :   IN refresh mode in THuiRefreshMode
// ---------------------------------------------------------------------------
//    
void CAlfAppSrvSession::EnvSetRefreshModeL(const RMessage2& aMessage)
    {
    // 0: refresh mode (in)
    const THuiRefreshMode newMode = static_cast<THuiRefreshMode>(aMessage.Int0());
    
    if ( iRefreshMode != newMode )
        {
        iRefreshMode = newMode;
        
        if ( iFocused )
            {
            SharedHuiEnv()->SetRefreshMode( iRefreshMode );
            }
        }
    }
  
// ---------------------------------------------------------------------------
// class    :   CHuiEnv
// function :   SetMaxFrameRate
// param 0  :   IN framerate in Int
// ---------------------------------------------------------------------------
//    
void CAlfAppSrvSession::EnvSetMaxFrameRateL(const RMessage2& aMessage)
    {
    // 0: max framerate in TPckgC (in)
    TReal32 newRate = KAlfUseDefaultFrameRate;
    TPckg<TReal32> frameRatePckg(newRate);
    aMessage.Read(0,frameRatePckg);
    
    if ( !RealCompare( iMaxFrameRate, newRate ) )
        {
        iMaxFrameRate = newRate;
        
        if ( iFocused )
            {
            if ( RealCompare( iMaxFrameRate, KAlfUseDefaultFrameRate ) )
                {
                SharedHuiEnv()->SetMaxFrameRate( 
                    TReal32(AlfAppUi()->SettingsHandler().DefaultFramerate() ) );
                }
            else
                {
                SharedHuiEnv()->SetMaxFrameRate( iMaxFrameRate );
                }
            }
        }
    }
  
// ---------------------------------------------------------------------------
// class    :   CHuiEnv
// function :   ContinueRefresh
// ---------------------------------------------------------------------------
//    
void CAlfAppSrvSession::EnvContinueRefreshL(const RMessage2& /*aMessage*/)
    {
    SharedHuiEnv()->ContinueRefresh();
    }

// ---------------------------------------------------------------------------
// class    :   CHuiEnv
// function :   PauseRefresh
// ---------------------------------------------------------------------------
//    
void CAlfAppSrvSession::EnvPauseRefreshL(const RMessage2& /*aMessage*/)
    {
    SharedHuiEnv()->PauseRefresh();
    }
   
// ---------------------------------------------------------------------------
// class    :   CHuiEnv
// function :   RefreshCallBack
// ---------------------------------------------------------------------------
//   
void CAlfAppSrvSession::EnvRefreshCallBackL(const RMessage2& /*aMessage*/)
    {
    CHuiEnv::RefreshCallBack( SharedHuiEnv() );
    }

// ---------------------------------------------------------------------------
// class    :   CHuiEnv
// function :   SetIdleThreshold
// param 0  :   IN Idle threshold time in milliseconds
// ---------------------------------------------------------------------------
//    
void CAlfAppSrvSession::EnvSetIdleThresholdL(const RMessage2& aMessage)
    {
    // 0: time in milliseconds (in)
    const TInt time = (TInt)aMessage.Int0();
    
    if ( iIdleThreshold != time )
        {
        iIdleThreshold = time;
        
        if ( iFocused )
            {
            SharedHuiEnv()->SetIdleThreshold( iIdleThreshold );
            }
        }
    }
    
// ---------------------------------------------------------------------------
// class    : CHuiEnv  
// function : Renderer  
// param 0  : IN/OUT renderer 
// ---------------------------------------------------------------------------
//  
void CAlfAppSrvSession::EnvRendererL(const RMessage2& aMessage)
    {
    // Parse parameters

    // 0: renderer (in/out)
    TInt renderer = 0;
    TPckg<TInt> rendererPckg(renderer);
    aMessage.Read(0,rendererPckg);
    renderer = SharedHuiEnv()->Renderer();    
    aMessage.Write(0,rendererPckg);    
    }  
    
// ---------------------------------------------------------------------------
// class    :   CHuiRoster
// function :   Hide
// param 0  :   IN Handle to CHuiControlGroup object
// param 1  :   IN Handle to CHuiDisplay object
// ---------------------------------------------------------------------------
//    
void CAlfAppSrvSession::RosterHideL(const RMessage2& aMessage)
    {
    // Parse parameters
    // 0: control group handle (in)
    const TInt cntrlGroupHandle = aMessage.Int0();
    CAlfSrvSubSessionBase& subSession1 = SubSession( cntrlGroupHandle );
    CAlfSrvControlGroupSubSession& controlGroupSubSession = 
        static_cast<CAlfSrvControlGroupSubSession&>(subSession1);
    CHuiControlGroup& controlGroup = controlGroupSubSession.ControlGroup();
                
    // 1: display handle (in)
    const TInt displayHandle = aMessage.Int1();
    CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle );
    CAlfSrvDisplaySubSession& displaySubSession = 
        static_cast<CAlfSrvDisplaySubSession&>(subSession2);
    CHuiDisplay& display = displaySubSession.Display();

    // hide
    controlGroupSubSession.SetIsShown( EFalse );
  
    
#ifdef SYMBIAN_BUILD_GCE
    CHuiLayout* hostContainer = controlGroup.Control(0).ContainerLayout( NULL );      
    controlGroup.SetAcceptInput(EFalse);
    if(hostContainer)
        hostContainer->SetFlags(EHuiVisualFlagUnderOpaqueHint);
#else    
    // hide from the roster only if session is focused
    if ( iFocused )
        {
        display.Roster().Hide(controlGroup);
        }
    else // otherwise remove from the iControlGroupOrder array
        {
         TInt index = iControlGroupOrder.Find( &controlGroup );
         if(  index != KErrNotFound)
             {
             iControlGroupOrder.Remove( index );
             }
        }
#endif
    }
    
// ---------------------------------------------------------------------------
// class    :   CHuiRoster
// function :   ShowVisualL
// param 0  :   IN Handle to CHuiVisual object
// param 1  :   IN Handle to CHuiDisplay object
// ---------------------------------------------------------------------------
//     
void CAlfAppSrvSession::RosterShowVisualL(const RMessage2& aMessage)
    {
    // Parse parameters
    // 0: visual handle (in)
    TAny* huiVisualAnyPtr = GetInterfaceL( EHuiObjectTypeVisual, aMessage.Int0() );
    CHuiVisual* huiVisual = static_cast<CHuiVisual*>(huiVisualAnyPtr);
    
    // 1: display handle (in)
    const TInt displayHandle = aMessage.Int1();
    CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle );
    CAlfSrvDisplaySubSession& displaySubSession = 
        static_cast<CAlfSrvDisplaySubSession&>(subSession2);
    CHuiDisplay& display = displaySubSession.Display();
    
    // show visual
    display.Roster().ShowVisualL(huiVisual);
    }
    
// ---------------------------------------------------------------------------
// class    :   CHuiRoster
// function :   HideVisual
// param 0  :   IN Handle to CHuiVisual object
// param 1  :   IN Handle to CHuiDisplay object
// ---------------------------------------------------------------------------
// 
void CAlfAppSrvSession::RosterHideVisualL(const RMessage2& aMessage)
    {
    // Parse parameters
    // 0: visual handle (in)
    TAny* huiVisualAnyPtr = GetInterfaceL( EHuiObjectTypeVisual, aMessage.Int0() );
    CHuiVisual* huiVisual = static_cast<CHuiVisual*>(huiVisualAnyPtr);
    
    // 1: display handle (in)
    const TInt displayHandle = aMessage.Int1();
    CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle );
    CAlfSrvDisplaySubSession& displaySubSession = 
        static_cast<CAlfSrvDisplaySubSession&>(subSession2);
    CHuiDisplay& display = displaySubSession.Display();
    
    // show visual
    display.Roster().HideVisual(huiVisual);
    }
  
// ---------------------------------------------------------------------------
// class    :   CHuiRoster
// function :   MoveVisualToFront
// param 0  :   IN Handle to CHuiVisual object
// param 1  :   IN Handle to CHuiDisplay object
// ---------------------------------------------------------------------------
//   
void CAlfAppSrvSession::RosterMoveVisualToFrontL(const RMessage2& aMessage)
    {
    // Parse parameters
    // 0: visual handle (in)
    TAny* huiVisualAnyPtr = GetInterfaceL( EHuiObjectTypeVisual, aMessage.Int0() );
    CHuiVisual* huiVisual = static_cast<CHuiVisual*>(huiVisualAnyPtr);
    
    // 1: display handle (in)
    const TInt displayHandle = aMessage.Int1();
    CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle );
    CAlfSrvDisplaySubSession& displaySubSession = 
        static_cast<CAlfSrvDisplaySubSession&>(subSession2);
    CHuiDisplay& display = displaySubSession.Display();
    
    // move visual to front
#ifdef SYMBIAN_BUILD_GCE
    TInt firstAlfPositionInRoster = AlfAppUi()->FirstAlfControlGroupIndex();
    display.Roster().Move(huiVisual, firstAlfPositionInRoster); 

#else    
    display.Roster().MoveVisualToFront(huiVisual);
#endif
    }

// ---------------------------------------------------------------------------
// class    :   CHuiRoster
// function :   Observers().AppendIfNotFoundL, Observers.RemoveIfFound
// param 0  :   IN flags
// param 1  :   IN Handle to CHuiControl object
// param 2  :   IN Handle to CHuiDisplay object
// ---------------------------------------------------------------------------
//      
void CAlfAppSrvSession::RosterSetPointerEventFlagsL(const RMessage2& aMessage)
    {
    // 0: flags (in)
    const TInt flags = aMessage.Int0();
    
    // 1: control handle (in)
    TAny* huiControlAnyPtr = GetInterfaceL( EHuiObjectTypeControl, aMessage.Int1() );
    CHuiControl* huiControl = static_cast<CHuiControl*>(huiControlAnyPtr);
    
    // 2: display handle (in)
    const TInt displayHandle = aMessage.Int2();
    CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle );
    CAlfSrvDisplaySubSession& displaySubSession = 
        static_cast<CAlfSrvDisplaySubSession&>(subSession2);
    CHuiDisplay& display = displaySubSession.Display();
    
    if ( flags & EAlfPointerEventReportDrag )
        {
        display.Roster().Observers(EHuiInputPointerDrag).AppendIfNotFoundL(*huiControl);
        }
    else
        {
        display.Roster().Observers(EHuiInputPointerDrag).RemoveIfFound(*huiControl);
        }
        
    if ( flags & EAlfPointerEventReportLongTap )
        {
        display.Roster().Observers(EHuiInputPointerLongTap).AppendIfNotFoundL(*huiControl);
        }
    else
        {
        display.Roster().Observers(EHuiInputPointerLongTap).RemoveIfFound(*huiControl);
        }
        
    if ( flags & EAlfPointerEventReportUnhandled  )
        {
        display.Roster().Observers(EHuiInputPointerUnhandled).AppendIfNotFoundL(*huiControl);
        }
    else
        {
        display.Roster().Observers(EHuiInputPointerUnhandled).RemoveIfFound(*huiControl);
        }
    }
    
// ---------------------------------------------------------------------------
// class    :   CHuiRoster
// function :   Observers().AppendIfNotFoundL
// param 0  :   IN TAlfPointerEventFlags
// param 1  :   IN Handle to CHuiControl object
// param 2  :   IN Handle to CHuiDisplay object
// ---------------------------------------------------------------------------
//      
void CAlfAppSrvSession::RosterAddPointerEventObserverL(const RMessage2& aMessage)
    {
    // 0: observer (in)
    const TAlfPointerEventFlags observer = (TAlfPointerEventFlags)aMessage.Int0();
    
    // 1: control handle (in)
    TAny* huiControlAnyPtr = GetInterfaceL( EHuiObjectTypeControl, aMessage.Int1() );
    CHuiControl* huiControl = static_cast<CHuiControl*>(huiControlAnyPtr);
    
    // 2: display handle (in)
    const TInt displayHandle = aMessage.Int2();
    CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle );
    CAlfSrvDisplaySubSession& displaySubSession = 
        static_cast<CAlfSrvDisplaySubSession&>(subSession2);
    CHuiDisplay& display = displaySubSession.Display();
    
    // add observer
    THuiInputType huiType = EHuiInputPointerDrag;
    switch ( observer )
        {
        case EAlfPointerEventReportDrag:
            huiType = EHuiInputPointerDrag;
            break;
        case EAlfPointerEventReportLongTap:
            huiType = EHuiInputPointerLongTap;
            break;
        case EAlfPointerEventReportUnhandled:
            huiType = EHuiInputPointerUnhandled;
            break;
        default:
            User::Leave( KErrNotSupported );
        }
        
    display.Roster().Observers(huiType).AppendIfNotFoundL(*huiControl);
    }
    
 // ---------------------------------------------------------------------------
// class    :   CHuiRoster
// function :   Observers.RemoveIfFound
// param 0  :   IN TAlfPointerEventFlags
// param 1  :   IN Handle to CHuiControl object
// param 2  :   IN Handle to CHuiDisplay object
// ---------------------------------------------------------------------------
//      
void CAlfAppSrvSession::RosterRemovePointerEventObserverL(const RMessage2& aMessage)
    {
    // 0: observer (in)
    const TAlfPointerEventFlags observer = (TAlfPointerEventFlags)aMessage.Int0();
    
    // 1: control handle (in)
    TAny* huiControlAnyPtr = GetInterfaceL( EHuiObjectTypeControl, aMessage.Int1() );
    CHuiControl* huiControl = static_cast<CHuiControl*>(huiControlAnyPtr);
    
    // 2: display handle (in)
    const TInt displayHandle = aMessage.Int2();
    CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle );
    CAlfSrvDisplaySubSession& displaySubSession = 
        static_cast<CAlfSrvDisplaySubSession&>(subSession2);
    CHuiDisplay& display = displaySubSession.Display();
    
    // remove observer
    THuiInputType huiType = EHuiInputPointerDrag;
    switch ( observer )
        {
        case EAlfPointerEventReportDrag:
            huiType = EHuiInputPointerDrag;
            break;
        case EAlfPointerEventReportLongTap:
            huiType = EHuiInputPointerLongTap;
            break;
        case EAlfPointerEventReportUnhandled:
            huiType = EHuiInputPointerUnhandled;
            break;
        default:
            User::Leave( KErrNotSupported );
        }
        
    display.Roster().Observers(huiType).RemoveIfFound(*huiControl);
    }

// ---------------------------------------------------------------------------
// class    :   CHuiRoster
// function :   
// param 0  :   
// ---------------------------------------------------------------------------
//      
void CAlfAppSrvSession::RosterSetPointerDragTresholdL(const RMessage2& aMessage)
    {
	// Parse parameters
    TAlfPointerEventDragTreshold params;
    TPckg<TAlfPointerEventDragTreshold> paramsPckg(params);
    aMessage.Read(0,paramsPckg);
    
    // control handle 
    TAny* huiControlAnyPtr = GetInterfaceL( EHuiObjectTypeControl, params.iControlHandle );
    CHuiControl* huiControl = static_cast<CHuiControl*>(huiControlAnyPtr);
    
	// display handle
    CAlfSrvSubSessionBase& subSession2 = SubSession( params.iDisplayHandle );
    CAlfSrvDisplaySubSession& displaySubSession = 
        static_cast<CAlfSrvDisplaySubSession&>(subSession2);
    CHuiDisplay& display = displaySubSession.Display();
    
	THuiXYMetric huiXYMetric;
    AlfXYMetricUtility::CopyMetric(params.iXYMetric, huiXYMetric);    
    
    display.Roster().SetPointerDragThresholdL(*huiControl, huiXYMetric );
    
    }

// ---------------------------------------------------------------------------
// class    :   CHuiRoster
// function :   
// param 0  :   
// ---------------------------------------------------------------------------
//      
void CAlfAppSrvSession::RosterDisableLongTapEventWhenDraggingL(const RMessage2& aMessage)
    {
	// Parse parameters
    // control handle (in)
    TAny* huiControlAnyPtr = GetInterfaceL( EHuiObjectTypeControl, aMessage.Int0() );
    CHuiControl* huiControl = static_cast<CHuiControl*>(huiControlAnyPtr);

    // observer (in)
    const TBool disable = (TBool)aMessage.Int1();
    
    // display handle (in)
    const TInt displayHandle = aMessage.Int2();
    CAlfSrvSubSessionBase& subSession2 = SubSession( displayHandle );
    CAlfSrvDisplaySubSession& displaySubSession = 
        static_cast<CAlfSrvDisplaySubSession&>(subSession2);
    CHuiDisplay& display = displaySubSession.Display();
    
	display.Roster().DisableLongTapEventsWhenDraggingL(*huiControl, disable);
    }

// ---------------------------------------------------------------------------
// class    :   
// function :   
// param 0  :   
// param 1  :   
// ---------------------------------------------------------------------------
//  
void CAlfAppSrvSession::TextureCreateL(const RMessage2& aMessage)
    {
    // Owner id is stored in UpdateTextureOwnerIdL via IPC command 
    // EAlfTextureUpdateOwnerId.
    
    // Parse parameters

    // 0: handle (in/out)
    TInt handle;
    TPckg<TInt> handlePckg(handle);
    aMessage.Read(0,handlePckg);

    // 1: TAlfTextureCreateParams (in)
    TAlfCreateTextureParams params;
    TPckg<TAlfCreateTextureParams> paramsPckg(params);
    aMessage.Read(1,paramsPckg);


    CHuiEnv* env = SharedHuiEnv();
    if (params.iBitmapHandle && params.iId != 0) 
        {            
        const TInt bitmapHandle = params.iBitmapHandle;
        const TInt maskHandle = params.iMaskBitmapHandle;
    	const TInt flags = params.iFlags;
        const TInt managerId = params.iManagerId;
        const TInt id = 
            AlfTextureManager().CreateTextureId(
                TextureOwnerId(),
                params.iId, 
                managerId, 
                ETrue );

    	CSharedBitmapProvider* provider = new (ELeave) CSharedBitmapProvider(bitmapHandle, maskHandle);
        CleanupStack::PushL(provider);
    	
        // Convert the TAlfTextureFlags to THuiTextureUploadFlags
        TInt inputFlags = flags;
        inputFlags &= ~EAlfTextureFlagSkinContent;
        inputFlags &= ~EAlfTextureFlagAutoSize;
        inputFlags &= ~EAlfTextureFlagLoadAnimAsImage;
        
        TBool textureAlreadyExists = (env->TextureManager().Texture(id) != &env->TextureManager().BlankTexture());
        
        // If we cannot load alf client texture, then it's quite hard to recover from that situation.
        // If texture is sufficiently large, we will release optional GPU RAM automatically.
		// Still, client should beforehand use GOOM to make sure there is enough memory.
        if ( ShouldReleaseGpuMemoryL( *provider, id ) )
            {
            ReleaseOptionalGpuMemory();
            }
        
        CHuiTexture& texture = env->TextureManager().CreateTextureL(id,
                                     provider,
                                     (THuiTextureUploadFlags)inputFlags);

        // If we are reusing deleted texture, remove it from "deleted" array
        TInt index = iTextures.Find(&texture);
        if (index == KErrNotFound)
           {
           iTextures.Append(env->TextureManager().Texture(id));                
           }                    


        // Add texture to skin content
        texture.SetSkinContent((flags & EAlfTextureFlagSkinContent) != 0);

        // Add texture to automatic dynamic size calculations
        texture.EnableAutoSizeCalculation((flags & EAlfTextureFlagAutoSize) != 0);
        
        // Check if texture already existed, if yes then we need to update its content
        // because 
        if (textureAlreadyExists)
            {
            CFbsBitmap* bitmap = NULL;
            CFbsBitmap* mask = NULL;
            provider->ProvideBitmapL(0, bitmap, mask);
            CleanupStack::PushL(bitmap);
            CleanupStack::PushL(mask);
            texture.EnableShadow((flags & EHuiTextureUploadFlagGenerateShadow) != 0);            
            TSize bitmapSize = bitmap->SizeInPixels();
            if (bitmapSize.iWidth != 0 && bitmapSize.iHeight != 0)
                {
                // This uses direct upload if possible and specified in the upload flags
                TRAPD(err, env->TextureManager().UpdateTextureFromBitmapL(id, provider))        
                
                if (err != KErrNone)
                    {
                    // We do this because texture may be in undetermined state (?)
                    texture.Reset();    
                    User::Leave(err);
                    }
                }
            texture.SetSize(bitmap->SizeInPixels());
            CleanupStack::PopAndDestroy(2); // bitmap, mask
            }  
                                     
        // We delete provider here, because the release/restore
        // is supported in the client library. There is currently
        // no need to restore textures in the server.
        CleanupStack::PopAndDestroy(); // provider;

        // Write parameters
        handle = TInt((MHuiTexture*)(&texture));
        aMessage.Write(0,handlePckg);
        }
    else
        {
        CHuiTexture& texture = env->TextureManager().BlankTexture();    
        // Write parameters
        handle = TInt((MHuiTexture*)(&texture));
        aMessage.Write(0,handlePckg);
        }    
    }

void CAlfAppSrvSession::TextureCreateAnimatedL(const RMessage2& aMessage)
    {
    // Parse parameters

    // 0: handle (in/out)
    TInt handle = 0;
    TPckg<TInt> handlePckg(handle);
    aMessage.Read(0,handlePckg);

    // 1: TAlfTextureCreateParams (in)
    TAlfCreateTextureAnimatedParams params;
    TPckg<TAlfCreateTextureAnimatedParams> paramsPckg(params);
    aMessage.Read(1,paramsPckg);
    CHuiEnv* env = SharedHuiEnv();
    
    CHuiGifAnimationTexture* animtext = CHuiGifAnimationTexture::NewL(params.iFilename,env->TextureManager(),params.iId, (THuiTextureUploadFlags)(params.iFlags));
    //MHuiTexture* foo = dynamic_cast<MHuiTexture*>(animtext);
    iAnimatedTextures.Append(animtext);
    handle = TInt((MHuiTexture*)(animtext));
    aMessage.Write(0,handlePckg);
    }




// ---------------------------------------------------------------------------
// class    :   
// function :   
// param 0  :   
// param 1  :   
// ---------------------------------------------------------------------------
//  
void CAlfAppSrvSession::TextureLoadL(const RMessage2& aMessage)
    {
    // Owner id is stored in UpdateTextureOwnerIdL via IPC command 
    // EAlfTextureUpdateOwnerId.

    // 0: handle (in/out)
    TInt handle = 0;
    TPckg<TInt> handlePckg(handle);
    aMessage.Read(0,handlePckg);

    // 1: TAlfTextureLoadParams (in)
    TAlfLoadTextureParams params;
    TPckg<TAlfLoadTextureParams> paramsPckg(params);
    aMessage.Read(1,paramsPckg);

    const TInt bitmapHandle = params.iBitmapHandle;
    const TInt maskHandle = params.iMaskBitmapHandle;
	const TInt flags = params.iFlags;
    const TInt managerId = params.iManagerId;
    const TInt id = 
        AlfTextureManager().CreateTextureId(
            TextureOwnerId(),
            params.iId, 
            managerId, 
            ETrue );

    CHuiEnv* env = SharedHuiEnv();
    if (bitmapHandle && params.iId != 0)
        {            
    	CSharedBitmapProvider* provider = 
    	    new (ELeave) CSharedBitmapProvider(bitmapHandle, maskHandle);
        CleanupStack::PushL(provider);
        
        // Convert the TAlfTextureFlags to THuiTextureUploadFlags
        TInt inputFlags = (THuiTextureUploadFlags)flags;
        inputFlags &= ~EAlfTextureFlagSkinContent;
        inputFlags &= ~EAlfTextureFlagAutoSize;
        inputFlags &= ~EAlfTextureFlagLoadAnimAsImage;
        
        TBool textureAlreadyExists = (env->TextureManager().Texture(id) != &env->TextureManager().BlankTexture());

        // Make sure texture exists
        CHuiTexture& textureRef = env->TextureManager().CreateTextureL(id, provider, THuiTextureUploadFlags(inputFlags));

        // If we are reusing deleted texture, remove it from "deleted" array
        TInt index = iTextures.Find(&textureRef);
        if (index == KErrNotFound)
           {
           iTextures.Append(env->TextureManager().Texture(id));                
           }                    
        
        // Add texture to skin content
        textureRef.SetSkinContent((flags & EAlfTextureFlagSkinContent) != 0);

        // Add texture to automatic dynamic size calculations
        textureRef.EnableAutoSizeCalculation((flags & EAlfTextureFlagAutoSize) != 0);
    	    	
        // Upload texture, this is needed because CreateTexture does not necessarely do anything if texture
        // already exists.
        if (textureAlreadyExists)
            {                
            CFbsBitmap* bitmap = NULL;
            CFbsBitmap* mask = NULL;
            provider->ProvideBitmapL(id, bitmap, mask);
            CleanupStack::PushL(bitmap);
            CleanupStack::PushL(mask);
            textureRef.EnableShadow((flags & EHuiTextureUploadFlagGenerateShadow) != 0);            
            TSize bitmapSize = bitmap->SizeInPixels();
            if (bitmapSize.iWidth != 0 && bitmapSize.iHeight != 0)
                {
                // This uses direct upload if possible and specified in the upload flags
                TRAPD(err, env->TextureManager().UpdateTextureFromBitmapL(id, provider))        

                if (err != KErrNone)
                    {
                    // We do this because texture may be in undetermined state (?)
                    textureRef.Reset();    
                    User::Leave(err);
                    }
                }
            textureRef.SetSize(bitmap->SizeInPixels());
            CleanupStack::PopAndDestroy(2); // bitmap, mask
            }
        // We delete provider here, because the release/restore
        // is supported in the client library. There is currently
        // no need to restore textures in the server.
        CleanupStack::PopAndDestroy( provider );


        // Write parameters
        handle = TInt((MHuiTexture*)(&textureRef));
        aMessage.Write(0,handlePckg);        
        }
    else
        {
        CHuiTexture& texture = env->TextureManager().BlankTexture();    
        // Write parameters
        handle = TInt((MHuiTexture*)(&texture));
        aMessage.Write(0,handlePckg);
        }    
        
    }

// ---------------------------------------------------------------------------
// class    : CHuiTextureManager  
// function : UnloadTexture  
// param 0  : IN Texture id  
// ---------------------------------------------------------------------------
//  
void CAlfAppSrvSession::TextureUnload(const RMessage2& aMessage)
    {
    // Parse parameters

    // 0: id (in)
   	const TInt originalId = aMessage.Int0();
   	const TInt managerId = aMessage.Int1();

	if (originalId != 0)
	    {
        const TInt id = 
            AlfTextureManager().ExistingTextureId(
                TextureOwnerId(), originalId, managerId);
        
    	if ( id != 0 && 
    	     AlfTextureManager().ReleaseTextureId( 
    	        TextureOwnerId(), originalId, managerId ) == 0)
    	    {
            if ( !managerId )
                {
                RemoveTextureInfo( originalId );
                }

            CHuiEnv* env = SharedHuiEnv();    	
           	env->TextureManager().UnloadTexture(id);                                         	            	        
    	    }
	    }
    }

// ---------------------------------------------------------------------------
// class    : 
// function : 
// param 0  : IN Texture id  
// ---------------------------------------------------------------------------
//  
void CAlfAppSrvSession::TextureDelete(const RMessage2& aMessage)
    {
    // Parse parameters

    // 0: id (in)
   	const TInt originalId = aMessage.Int0();
   	const TInt managerId = aMessage.Int1();

	if (originalId != 0)
	    {
        const TInt id = 
            AlfTextureManager().ExistingTextureId( 
                TextureOwnerId(), originalId, managerId );
        
    	if ( id != 0 && 
    	     AlfTextureManager().ReleaseTextureId( 
    	        TextureOwnerId(), originalId, managerId ) == 0)
    	    {
            CHuiEnv* env = SharedHuiEnv();
           	env->TextureManager().UnloadTexture(id);
           	
            if ( !managerId )
                {
                RemoveTextureInfo( originalId );
                }
           	
            if ( AlfTextureManager().DeleteTextureId(
                     TextureOwnerId(), originalId, managerId) == 0 )
                {
        	    // For now just unload textures, actual deletion happens 
        	    // when session is closed (for safety reasons).
                CHuiTexture* texture = env->TextureManager().Texture(id); 
                if (texture)
                    {
                    // We should set texture attributes to default values
                    // here if we recycle hui-textures during this session.
                    texture->SetAutoSizeParams(THuiTextureAutoSizeParams());
                    texture->EnableShadow(EFalse);
                    texture->SetSkinContent(EFalse);
                    
                    if (iTextures.Find(texture) == KErrNotFound)
                        {
                        iTextures.Append(texture);                
                        }                    
                    }                                
                }
    	    }
	    }
    }

// ---------------------------------------------------------------------------
// class    : CHuiTextureManager  
// function :  
// param 0  : IN Texture id  
// ---------------------------------------------------------------------------
//  
void CAlfAppSrvSession::TextureRelease(const RMessage2& aMessage)
    {
    // Parse parameters

    // 0: id (in)
   	const TInt originalId = aMessage.Int0();
   	const TInt managerId = aMessage.Int1();

	if (originalId != 0)
	    {
	    // Just release texture id
        AlfTextureManager().ReleaseTextureId(
            TextureOwnerId(), originalId, managerId );	    
	    }
    }

// ---------------------------------------------------------------------------
// class    : CHuiTextureManager  
// function :  
// param 0  : IN Texture id  
// ---------------------------------------------------------------------------
//  
void CAlfAppSrvSession::TextureRestore(const RMessage2& aMessage)
    {
    // Parse parameters

    // 0: id (in)
   	const TInt originalId = aMessage.Int0();
   	const TInt managerId = aMessage.Int1();

	if (originalId != 0)
	    {
	    // Just restore texture id
        AlfTextureManager().CreateTextureId(
            TextureOwnerId(), originalId, managerId, EFalse );
	    }
    }

// ---------------------------------------------------------------------------
// class    : CHuiTextureManager  
// function :  
// param 0  : IN Texture id  
// ---------------------------------------------------------------------------
//  
void CAlfAppSrvSession::TextureNotifySkinChanged(const RMessage2& aMessage)
    {
    // Parse parameters

    // 0: id (in)
   	const TInt originalId = aMessage.Int0();
   	const TInt managerId = aMessage.Int1();

	if (originalId != 0)
	    {
        const TInt id = 
            AlfTextureManager().ExistingTextureId( 
                TextureOwnerId(), originalId, managerId );
        
    	if ( id != 0 && 
    	     AlfTextureManager().ValidateSkinForTextureId( 
    	        TextureOwnerId(), originalId, managerId ) == 0)
    	    {
            CHuiEnv* env = SharedHuiEnv();    	
           	env->TextureManager().UnloadTexture(id);                                         	            	        
    	    }
	    }
    }

static CHuiTexture* CastTexture( MHuiTexture* aMHuiTexture )
    {
    CHuiTexture* resultCHuiTexture = NULL;
    if ( aMHuiTexture )
        {
        // only CHuiTexture implements the MHuiShadowedTexture interface
        MHuiShadowedTexture* shadowedTexture = aMHuiTexture->ShadowedTexture();
        if ( shadowedTexture )
            {
            resultCHuiTexture = static_cast<CHuiTexture*>( shadowedTexture );
            }
        }
            
    return resultCHuiTexture;
    }

// ---------------------------------------------------------------------------
// class    :   
// function :   
// param 0  :   
// param 1  :   
// ---------------------------------------------------------------------------
//  
void CAlfAppSrvSession::TextureBlurL(const RMessage2& aMessage)
    {
    // Parse parameters

    // 0: TAlfBlurTextureParams (in)
    TAlfBlurTextureParams params;
    TPckg<TAlfBlurTextureParams> paramsPckg(params);
    aMessage.Read(0,paramsPckg);

    CHuiEnv* env = SharedHuiEnv();
    if (params.iServerSideSrcHandle && params.iServerSideDstHandle)
        {
        CHuiTexture* srcTexture = CastTexture(reinterpret_cast<MHuiTexture*>(params.iServerSideSrcHandle));
        CHuiTexture* dstTexture = CastTexture(reinterpret_cast<MHuiTexture*>(params.iServerSideDstHandle));
        
        if (srcTexture && dstTexture)
            {
            
            const THuiTextureHandle srcHandle = srcTexture->Handle();
            THuiTextureHandle dstHandle = dstTexture->Handle();
            const TSize size = params.iPreferredSize;
                
            env->TextureManager().Processor().BlurL(srcHandle,
                dstHandle, 
                size,
                params.iFilterSize,
                params.iFlag);            
            }
        else
            {
            User::Leave(KErrArgument);
            }
        }
    }

// ---------------------------------------------------------------------------
// class    :   
// function :   
// param 0  :   
// param 1  :   
// ---------------------------------------------------------------------------
//  
void CAlfAppSrvSession::TextureHasContentL(const RMessage2& aMessage)
    {

    // 0: ret val (in/out)
    TBool retVal = EFalse;
    TPckg<TBool> retValPckg(retVal);
    aMessage.Read(0,retValPckg);

    // 1: id (in)
   	const TInt originalId = aMessage.Int1();
   	
    // 2: manager id (in)
   	const TInt managerId = aMessage.Int2();

	if (originalId != 0)
	    {
        const TInt id = 
            AlfTextureManager().ExistingTextureId( 
                TextureOwnerId(), originalId, managerId, ETrue);
        
        if (id != 0)
            {
            CHuiEnv* env = SharedHuiEnv();    	
            CHuiTexture* tex = env->TextureManager().Texture(id);                                         	            	        
            if (tex)
                {
                retVal = tex->HasContent();               
                }                
            }
	    }
    aMessage.Write(0,retValPckg);        
    }

void CAlfAppSrvSession::TextureStartAnimation(const RMessage2& aMessage)
    {
    TInt id = aMessage.Int0();
    CHuiGifAnimationTexture* tex = NULL;
    for (TInt index = 0; index < iAnimatedTextures.Count(); index++)
        {
        tex = iAnimatedTextures.operator[](index);
        if (tex->Id() == id)
            {
            tex->Start();
            break;
            }
        }
    }
    
void CAlfAppSrvSession::TextureStopAnimation(const RMessage2& aMessage)
    {
    TInt id = aMessage.Int0();
    CHuiGifAnimationTexture* tex = NULL;
    for (TInt index = 0; index < iAnimatedTextures.Count(); index++)
        {
        tex = iAnimatedTextures.operator[](index);
        if (tex->Id() == id)
            {
            tex->Stop();
            break;
            }
        }
    }

// ---------------------------------------------------------------------------
// class    :   
// function :   
// param 0  :   
// param 1  :   
// ---------------------------------------------------------------------------
//  
void CAlfAppSrvSession::TextureSetAutoSizeParamsL(const RMessage2& aMessage)
    {

    // 0: id (in)
   	const TInt originalId = aMessage.Int0();
   	
    // 1: manager id (in)
   	const TInt managerId = aMessage.Int1();

    // 2: params (in)
    TAlfTextureAutoSizeParams params;
    TPckg<TAlfTextureAutoSizeParams> paramPckg(params);
    aMessage.Read(2,paramPckg);


	if (originalId != 0)
	    {
        const TInt id = 
            AlfTextureManager().ExistingTextureId( 
                TextureOwnerId(), originalId, managerId, ETrue);
        
        if (id != 0)
            {
            CHuiEnv* env = SharedHuiEnv();    	
            CHuiTexture* tex = env->TextureManager().Texture(id);                                         	            	        
            if (tex)
                {
                THuiTextureAutoSizeParams* huiparams = (THuiTextureAutoSizeParams*) &params;                
                tex->SetAutoSizeParams(*huiparams);               
                }                
            }
	    }
    }

void CAlfAppSrvSession::LayoutMetricsTextStyleDataL(const RMessage2& aMessage)
    {
    // 0: ret val (in/out)
    TInt retVal = 0;
    TPckg<TInt> retValPckg(retVal);
    aMessage.Read(0,retValPckg);

    // 1: textStyle (in)
   	const TInt textStyle = aMessage.Int1();
   	
    CHuiEnv* env = SharedHuiEnv();
    retVal = env->TextStyleManager().TextStyle(textStyle)->FontStyleId();    	   	
    
    aMessage.Write(0,retValPckg);                
    }
    
TBool CAlfAppSrvSession::RequireTextureOwnerId(const RMessage2& aMessage)
    {
    if ( !iTextureOwnedIdSet )
        {
        AlfPanicClient( aMessage, EAlfSrvTexturePanicTextureOwnerIdNotUpdated );        
        }
        
    return iTextureOwnedIdSet;
    }
    
void CAlfAppSrvSession::UpdateTextureOwnerIdL(const RMessage2& aMessage)
    {
    if ( !iTextureOwnedIdSet )
        {
        // Open process, get id and then close.
        RThread client;
        User::LeaveIfError( aMessage.Client(client) );
        CleanupClosePushL( client );
        RProcess process;
        User::LeaveIfError( client.Process( process ) );
        TProcessId id = process.Id();
        process.Close();
        CleanupStack::PopAndDestroy( &client );
        
        // Register & then store owner id.
        AlfTextureManager().AddClientL( id, *this );
        iTextureOwnedIdSet = ETrue;
        iTextureOwnerId = id;
        }        
    }
    
inline TProcessId CAlfAppSrvSession::TextureOwnerId() const
    {
    __ASSERT_ALWAYS( iTextureOwnedIdSet, USER_INVARIANT() );
    return iTextureOwnerId;
    }

void CAlfAppSrvSession::ConfigureBatchCommandExecutionL( 
        const RMessage2& aMessage )
    {
    // This should be called only by unit tests. Anyway,
    // this has impact on this session only, so it does
    // not cause any problems.
    __ALFLOGSTRING1( "ConfigureBatchCommandExecutionL: %x", aMessage.Int0() )
    iExecutionFlags = aMessage.Int0();
    }

void CAlfAppSrvSession::ExecuteBatchCommandsL(const RMessage2& aMessage)
    {
    // First, let's try to execute using dynamic buffer..
    if ( !AllowExecuteUsingDynamicBuffer() || 
         !ExecuteBatchCommandsUsingDynamicBufferL( aMessage ) )
        {
        // If that fails, then try with fixed buffer.
        ExecuteBatchCommandsUsingFixedBufferL( aMessage );
        }
    }

TBool CAlfAppSrvSession::ExecuteBatchCommandsUsingDynamicBufferL( 
        const RMessage2& aMessage )
    {       
    TBool result = EFalse;

    CAlfAppServer* server = AlfServer();

    const TInt commonBatchBufferLength = 
        server->CommonCommandBatchBufferMaxLength();

    const TInt requiredBufferLength = aMessage.GetDesLengthL(0);

    TBool commonBatchBufferAcquired = EFalse;

    // This will finally hold reference to buffer to be used for
    // reading message from client side.
    TPtr8 ptrBuffer( 0, 0 );

    // First, try to acquire common command batch buffer
    // (if it's not in use and it has sufficient space)
    if ( AllowExecuteUsingCommonBuffer() &&
         ( commonBatchBufferLength >= requiredBufferLength ) )
        {
        commonBatchBufferAcquired = 
            server->AcquireCommonCommandBatchBuffer( ptrBuffer );
        }

    // If common command batch buffer were not usable,
    // let's try to allocate bigger buffer.
    HBufC8* memoryBuffer = NULL;
    if ( commonBatchBufferAcquired )
        {
        result = ETrue;
        }
    else
        {
        memoryBuffer = HBufC8::New( requiredBufferLength );
        if ( memoryBuffer )
            {
            result = ETrue;
            ptrBuffer.Set( memoryBuffer->Des() );
            }
        }

    if ( result )
        {
        TInt err = aMessage.Read( 0, ptrBuffer );

        if ( err != KErrNone )
            {
            // Release and then leave.
            if ( memoryBuffer )
                {
                delete memoryBuffer;
                memoryBuffer = NULL;
                }
            if ( commonBatchBufferAcquired )
                {
                server->ReleaseCommonCommandBatchBuffer();
                }
            
            User::Leave( err );
            }

        TInt dummy;
        TInt length = 0;

        // Note - this method is implemented so that this works even in OOM, that's
        // why TRAP is used here intentionally.
        TRAP( err, length = ExecuteCommandsFromDescriptorL( ptrBuffer, dummy ) );
        const TInt ptrBufferLength = ptrBuffer.Length();

        // Release - note that buffer length must be fetched before deletion.
        if ( memoryBuffer )
            {
            delete memoryBuffer;
            memoryBuffer = NULL;
            }
        if ( commonBatchBufferAcquired )
            {
            server->ReleaseCommonCommandBatchBuffer();
            }

#ifdef _ALF_LOGGING
        if ( err != KErrNone )
            {
            __ALFLOGSTRING3( 
                "ExecuteBatchCommandsUsingDynamicBufferL execution failed, err=%d (%d,%d)", 
                err, length, ptrBufferLength )
            }
#endif // _ALF_LOGGING

        if ( !err && ( length != ptrBufferLength ) )
            {
            // All commands were not executed!
            __ALFLOGSTRING2( 
                "ExecuteBatchCommandsUsingDynamicBufferL corrupted buffer (%d,%d)", 
                length, ptrBufferLength )
            err = KErrCorrupt;
            }

        User::LeaveIfError( err );
        }

    return result;
    }

void CAlfAppSrvSession::ExecuteBatchCommandsUsingFixedBufferL( 
        const RMessage2& aMessage )
    {
    CAlfAppServer* server = AlfServer();
    const TInt messageLength = aMessage.GetDesLengthL(0);

    TBufC8< KAlfStackBatchBufferSize > stackBuffer;
    TPtr8 ptrBuffer( stackBuffer.Des() );

    TBool commonBatchBufferAcquired = EFalse;
    if ( AllowExecuteUsingCommonBuffer() )
        {
        commonBatchBufferAcquired = 
            server->AcquireCommonCommandBatchBuffer( ptrBuffer );
        }
    
    TInt length = 0;

    // Note - this method is implemented so that this works even in OOM, that's
    // why TRAP is used here intentionally.
    TRAPD( err, length = 
        ExecuteBatchCommandsUsingBufferL( ptrBuffer, messageLength, aMessage ) );

    if ( commonBatchBufferAcquired )
        {
        server->ReleaseCommonCommandBatchBuffer();
        }

#ifdef _ALF_LOGGING
    if ( err != KErrNone )
        {
        __ALFLOGSTRING3( 
            "ExecuteBatchCommandsUsingFixedBufferL execution failed, err=%d (%d,%d)", 
            err, length, messageLength )
        }
#endif // _ALF_LOGGING

    if ( !err && ( length != messageLength ) )
        {
        // All commands were not executed!
        __ALFLOGSTRING2( 
            "ExecuteBatchCommandsUsingFixedBufferL corrupted buffer (%d,%d)", 
            length, messageLength )

        err = KErrCorrupt;
        }

    User::LeaveIfError( err );
    }

TInt CAlfAppSrvSession::ExecuteBatchCommandsUsingBufferL( 
        TDes8& aBuffer, 
        TInt aMessageLength,
        const RMessage2& aMessage )
    {
    const TInt bufferMaxLength = aBuffer.MaxLength();
    
    // It is assumed that bufferMaxLength > command header length.
    // If you check ExecuteBatchCommandsUsingFixedBufferL, you can see
    // that this assumption holds.

    TInt offset = 0;
    TBool failed = EFalse;

    while ( !failed && ( offset < aMessageLength ) ) 
        {
        aMessage.ReadL( 0, aBuffer, offset );

        TInt spaceNeeded = 0;
        offset += ExecuteCommandsFromDescriptorL( aBuffer, spaceNeeded );

        if ( spaceNeeded > ( aMessageLength - offset ) )
            {
            // More space is needed than there is left in message.
            failed = ETrue;
            }
        else if ( spaceNeeded > bufferMaxLength )
            {
            // Too bad, message does not fit to our fixed size buffer.
            // Let's try to allocate buffer for this.

            HBufC8* buffer = HBufC8::NewLC( spaceNeeded );
            TPtr8 bufferPtr = buffer->Des();

            aMessage.ReadL( 0, bufferPtr, offset );

            // Maximum length of buffer may be larger than spaceNeeded,
            // thus bufferPtr may be larger as well. But to keep this
            // simple, let's constraint to one message.
            if ( bufferPtr.Length() > spaceNeeded )
                {
                bufferPtr.SetLength( spaceNeeded );
                }
                
            if ( bufferPtr.Length() == spaceNeeded )
                {
                TInt dummy;
                TInt offsetDelta = 
                    ExecuteCommandsFromDescriptorL( bufferPtr, dummy );

                if ( offsetDelta == spaceNeeded )
                    {
                    // Move offset forward.
                    offset += offsetDelta;    
                    }
                else
                    {
                    // There was supposed to be exactly one message
                    // in buffer, but now there is not.
                    failed = ETrue;
                    }
                }
            else
                {
                // spaceNeeded amount of bytes were required for 
                // next message, but somehow we did not get that many bytes.
                failed = ETrue;
                }

            CleanupStack::PopAndDestroy( buffer );
            }
        else
            {
            // Do nothing - we can continue reading next part of buffer.
            }
        }

    return offset;
    }

TInt CAlfAppSrvSession::ExecuteCommandsFromDescriptorL( 
        const TDesC8& aSource, 
        TInt& aSpaceNeeded )
    {
    TPtrC8 unreadArea( aSource );
    aSpaceNeeded = 0;

    while ( !aSpaceNeeded && ( unreadArea.Length() > 0 ) )
        {
        TInt3 params(0,0,0);
        TPckg<TInt3> paramsPckg( params );

        // Check if there is complete parameter structure in unreadArea.
        const TInt paddedParamsPckgMaxLength = 
            AlfPaddedLength( paramsPckg.MaxLength() );
        if ( paddedParamsPckgMaxLength > unreadArea.Length() )
            {
            // Bail out from while loop.
            aSpaceNeeded = paddedParamsPckgMaxLength;
            }
        else
            {
            // Copy to local parameters.
            paramsPckg.Copy( unreadArea.Left( paramsPckg.MaxLength() ) );

            // Read parameters
            const TInt operation = params.iInt1;
            const TInt subSessionHandle = params.iInt2;
            const TInt inputBufferLength = params.iInt3;
            
            if ( inputBufferLength < 0 )
                {
                // Input buffer length must not be negative.
                __ALFLOGSTRING1( 
                    "ExecuteCommandsFromDescriptorL corrupted: neg. length %d",
                    inputBufferLength )
                User::Leave( KErrCorrupt );
                }
                
            const TInt paddedInputBufferLength = 
                AlfPaddedLength( inputBufferLength );
            
            if ( paddedParamsPckgMaxLength + paddedInputBufferLength < 0 )
                {
                // There must NOT be overflow.
                __ALFLOGSTRING1( 
                    "ExecuteCommandsFromDescriptorL corrupted: length %d",
                    inputBufferLength )
                User::Leave( KErrCorrupt );
                }

            // Check if there is complete input buffer in unreadArea.
            if ( paddedParamsPckgMaxLength + paddedInputBufferLength > 
                 unreadArea.Length() )
                {
                // Bail out from while loop.
                aSpaceNeeded = paddedParamsPckgMaxLength + paddedInputBufferLength;
                }
            else
                {                    
                // Now we know that all data is available. 
                // It's time to execute command.

                // Skip over parameters (already read above)
                unreadArea.Set( unreadArea.Mid( paddedParamsPckgMaxLength ) );
               
                // Read input buffer
                TPtrC8 inputbuffer = unreadArea.Left( inputBufferLength );
                unreadArea.Set( unreadArea.Mid( paddedInputBufferLength ) );
        
                if ( !CAlfAppSrvSessionBase::HasSession( subSessionHandle ) )
                    {
                    // Subsession handle must exist.
                    __ALFLOGSTRING1( 
                        "ExecuteCommandsFromDescriptorL corrupted: handle %d",
                        subSessionHandle )
                    User::Leave( KErrCorrupt );
                    }
        
                // Execute command
                CAlfSrvSubSessionBase& subsession = 
                    CAlfAppSrvSessionBase::SubSession( subSessionHandle );
                MAlfExtension* subsessionEx = subsession.AsCommandHandler();

                if ( !subsessionEx )
                    {
                    // Instance implementing extension interface must exist.
                    __ALFLOGSTRING1( 
                        "ExecuteCommandsFromDescriptorL corrupted: no ext, handle %d",
                        subSessionHandle )
                    User::Leave( KErrCorrupt );
                    }

                TBuf8<1> dummy;
#ifdef _ALF_LOGGING
                TRAPD( err,
                    subsessionEx->HandleCmdL( operation, inputbuffer, dummy ) );
                if ( err != KErrNone )
                    {
                    __ALFLOGSTRING3( 
                        "ExecuteCommandsFromDescriptorL HandleCmdL fail %d (subsession %d, operation %d)", 
                        err, subSessionHandle, operation )
                    }
                User::LeaveIfError( err );
#else
                subsessionEx->HandleCmdL( operation, inputbuffer, dummy );
#endif // _ALF_LOGGING
                }
            }
        }
    
    return aSource.Length() - unreadArea.Length();
    }

inline TBool CAlfAppSrvSession::AllowExecuteUsingDynamicBuffer() const
    {
    return ( iExecutionFlags & EAlfExecuteUsingDynamicBuffer );
    }

inline TBool CAlfAppSrvSession::AllowExecuteUsingCommonBuffer() const
    {
    return ( iExecutionFlags & EAlfExecuteUsingCommonBuffer );
    }

inline CAlfSrvTextureManager& CAlfAppSrvSession::AlfTextureManager()
    {
    return AlfServer()->TextureManager();
    }

void CAlfAppSrvSession::NotifyTextureInfo( const RMessage2& aMessage )
    {
    if ( iTextureInfoEvent.IsNull() )
        {
        iTextureInfoEvent = aMessage;
                
        // If there has been texture info updates, 
        // complete immediately.
        DeliverTextureInfo();
        }
    else
        {
        aMessage.Complete( KErrInUse );
        }   
    }

inline TBool CAlfAppSrvSession::HasPendingTextureInfo() const
    {
    TBool found = EFalse;
    
    for ( TInt i = 0; i < iTextureInfo.Count(); i++ )
        {
        const TAlfTextureInfo& info = iTextureInfo[ i ];
        if ( info.iFlags & TAlfTextureInfo::EAlfFlagTextureSizeChanged )
            {
            found = ETrue;
            break;
            }
        }
        
    return found;
    }
      
void CAlfAppSrvSession::DeliverTextureInfo()
    {
    if ( !(iFocused || iPartiallyVisible) || 
         iTextureInfoEvent.IsNull() || !HasPendingTextureInfo() )
        {
        // Events are not delivered if
        // - application does not have focus not partially visible
        // - there is no pending notification
        // - there is no texture info events to be delivered.
        return;
        }
        
    const TInt maxLength = iTextureInfoEvent.GetDesMaxLength( 0 );
    
    TAlfTextureInfoEvent event;
    TPckgC<TAlfTextureInfoEvent> eventPckg( event );
    const TInt eventPckgLength = eventPckg.Length();
    
    if ( maxLength <= eventPckgLength )
        {
        // Max length is less than size of one event buffer.
        // So bail out.
        iTextureInfoEvent.Complete( KErrBadDescriptor );
        }
    else
        {
        HBufC8* buffer = HBufC8::New( maxLength );
        if ( buffer )
            {
            TPtr8 ptr = buffer->Des();

            TInt priority = 0;
            TInt foundTexturePos = 0;
            
            const TInt totalTextureInfo = iTextureInfo.Count();
            
            while ( ( foundTexturePos != KErrNotFound ) && 
                    ( maxLength - ptr.Length() >= eventPckgLength ) )
                {
                // As long as there is space and another texture, 
                // append to buffer.
                
                // Find using current priority.
                foundTexturePos = 
                    FindNextTextureInfoForDelivery( priority, foundTexturePos );
                if ( ( foundTexturePos == KErrNotFound ) && !priority )
                    {
                    // If not found and priority was high, try
                    // with lower priority.
                    priority++;
                    foundTexturePos = 0;
                    
                    foundTexturePos = FindNextTextureInfoForDelivery( 
                        priority, foundTexturePos );
                    }
                                
                if ( foundTexturePos != KErrNotFound )
                    {
                    TAlfTextureInfo& current = iTextureInfo[ foundTexturePos ];
                    current.iFlags |= 
                        TAlfTextureInfo::EAlfFlagTextureDelivered;
                    current.iFlags &= 
                        ~TAlfTextureInfo::EAlfFlagTextureSizeChanged;
                    
                    // Append event data
                    event.iTextureId = current.iTextureId;
                    event.iTextureSize = current.iTextureSize;
                    ptr.Append( eventPckg );
                    
                    foundTexturePos++; // this has been delivered, skip to next
                    }
                }
        
            iTextureInfoEvent.Write( 0, ptr );
            iTextureInfoEvent.Complete( KErrNone );
            
            delete buffer;
            buffer = NULL;
            }
        else
            {
            // It is expected that maxLength is relatively small value.
            // So it's better to try again a bit later.
            }
        }
    }

TInt CAlfAppSrvSession::FindNextTextureInfoForDelivery( 
        TBool aPriority, TInt aStartPos ) const
    {
    const TInt count = iTextureInfo.Count();
    TInt result = KErrNotFound;
    
    for ( TInt index = aStartPos; index < count; index++ )
        {
        const TAlfTextureInfo& current = iTextureInfo[ index ];

        if ( ( current.iFlags & TAlfTextureInfo::EAlfFlagTextureSizeChanged ) &&
             ( current.iDeliveryPriority == aPriority ) )
            {
            result = index;
            break;
            }
        }
    
    return result;    
    }

TInt CAlfAppSrvSession::FindTextureInfoById( TInt aTextureId ) const
    {
    const TInt count = iTextureInfo.Count();
    
    // Optimization to handle the case that this method is called
    // several times using the same texture id.
    if ( iPreviousTextureInfoIndex < count )
        {
        if ( iTextureInfo[ iPreviousTextureInfoIndex ].iTextureId == 
             aTextureId )
            {
            return iPreviousTextureInfoIndex;
            }
        }
         
    
    TInt pos = KErrNotFound;
    
    for ( TInt i = 0; i < count; i++ )
        {
        if ( aTextureId == iTextureInfo[ i ].iTextureId )
            {
            pos = i;
            iPreviousTextureInfoIndex = pos;
            break;
            }
        }
    
    return pos;
    }

void CAlfAppSrvSession::RemoveTextureInfo( TInt aTextureId )
    {
    const TInt pos = FindTextureInfoById( aTextureId );
    if ( pos != KErrNotFound )
        {
        iTextureInfo.Remove( pos );
        }

    //Photos is never killed if it is excluded here. hence commenting
	/*
	if (!iTextureInfo.Count())
        {
        if (AlfAppUi()->BridgerClient())
            {
            AlfAppUi()->BridgerClient()->SendBlind(EAlfExcludeFromGoomTargets, TIpcArgs(SecureId(),ClientWindowGroup()));
            }
        }
	*/
    }

TInt CAlfAppSrvSession::GetTextureSize( 
        TInt aTextureId, 
        TSize& aTextureSize,
        TBool& aHasBeenDelivered )
    {
    TInt pos = FindTextureInfoById( aTextureId );
    if ( pos != KErrNotFound )
        {
        // TAlfTextureInfo struct was found - pos >= 0
        aTextureSize = iTextureInfo[ pos ].iTextureSize;
        aHasBeenDelivered = iTextureInfo[ pos ].iFlags & 
            TAlfTextureInfo::EAlfFlagTextureDelivered;
        }
        
    return pos != KErrNotFound;
    }
    
void CAlfAppSrvSession::SetTextureSize(
        TInt aTextureId,
        const TSize& aTextureSize,
        TInt aPriority )
    {
    const TBool highPriority = ( aPriority < 0 );
    aPriority = Max( 0, aPriority );
    aPriority = Min( 1, aPriority );

    if (!iTextureInfo.Count())
        {
        if (AlfAppUi()->BridgerClient())
            {
            AlfAppUi()->BridgerClient()->SendBlind(EAlfVolunteerForGoomTarget, TIpcArgs(SecureId(), ClientWindowGroup()));
            }
        }


    TInt pos = FindTextureInfoById( aTextureId );
    if ( pos != KErrNotFound )
        {
        // TAlfTextureInfo struct was found - pos >= 0
        TAlfTextureInfo& info = iTextureInfo[ pos ];
        info.iTextureSize = aTextureSize;
        info.iFlags |= TAlfTextureInfo::EAlfFlagTextureSizeChanged;
        info.iFlags &= ~TAlfTextureInfo::EAlfFlagTextureDelivered;
        info.iDeliveryPriority = aPriority;
        
        if ( highPriority )
            {
            // Move to the beginning. After this, above info
            // struct is invalid.
            TAlfTextureInfo tmp = iTextureInfo[ pos ];
            iTextureInfo.Remove( pos );
            iTextureInfo.Insert( tmp, 0 );
            }
        }
    else
        {
        // TAlfTextureInfo struct was not found - append a new one.
        TAlfTextureInfo info;
        info.iFlags = TAlfTextureInfo::EAlfFlagTextureSizeChanged;
        info.iTextureId = aTextureId;
        info.iTextureSize = aTextureSize;
        info.iDeliveryPriority = aPriority;
        
        if ( highPriority )
            {
            iTextureInfo.Insert( info, 0 );
            }
        else
            {
            iTextureInfo.Append( info );
            }
        }
    }
    
void CAlfAppSrvSession::RemoveTextureSize( TInt aTextureId )
    {
    RemoveTextureInfo( aTextureId );
    }
    
void CAlfAppSrvSession::TextureSizeChangesCompleted()
    {
    DeliverTextureInfo();
    }

// ---------------------------------------------------------------------------
// PostQtCommandBufferL
// ---------------------------------------------------------------------------
//
void CAlfAppSrvSession::PostQtCommandBufferL( const RMessage2& aMessage )
    {
  	TAlfQtCommandBufferParams params;
    TPckg<TAlfQtCommandBufferParams> paramsPckg(params);
    aMessage.Read(0,paramsPckg);    
	AlfAppUi()->PostQTCommandBufferL( params );  
	}

// ---------------------------------------------------------------------------
// ReportFrameRateBeginL
// ---------------------------------------------------------------------------
//
void CAlfAppSrvSession::ReportFrameRateBegin( const RMessage2& aMessage )
    {
    TInt32 id = aMessage.Int0();
    TFrameStamp* stamp = iFPSMeasurementArray.Find( id );
    // remove existing id, if any
    if ( stamp )
        {
        iFPSMeasurementArray.Remove(id);
        }
    iFPSMeasurementArray.Insert( id, TFrameStamp( CHuiStatic::FrameCount() ));
    }
            
// ---------------------------------------------------------------------------
// ReportFrameRateEndL
// ---------------------------------------------------------------------------
//
void CAlfAppSrvSession::ReportFrameRateEnd( const RMessage2& aMessage )
    {
    TInt32 id = aMessage.Int0();
    TFrameStamp FPSMeasurementEnd= TFrameStamp( CHuiStatic::FrameCount() );
    TBuf<40> logText;
            
    TFrameStamp* begin = iFPSMeasurementArray.Find( id );
    if ( begin )
        {
        TReal32 fps = FPSMeasurementEnd.FrameRate( *begin );
        iFPSMeasurementArray.Remove(id);
        
        logText.Format( _L("%d\t%4.2f"), id, fps );    
        RFileLogger::Write( KLogsDir, KAlfFPSLogFile, EFileLoggingModeAppend, logText );
        }
    else
        {
        logText.Format( _L("Id %d not found"), id );    
        RFileLogger::Write( KAlfFPSLogDir, KAlfFPSLogFile, EFileLoggingModeAppend, logText );
        }
    RDebug::Print(_L("CAlfAppSrvSession::ReportFrameRateL - %S"), &logText );
    }


// ---------------------------------------------------------------------------
// EnvEnableLowMemoryState
// ---------------------------------------------------------------------------
//    
void CAlfAppSrvSession::EnvEnableLowMemoryState(const RMessage2& aMessage)
    {
    TBool mode = aMessage.Int0();
    AlfAppUi()->NotifyLowMemory(mode);
    }

// ---------------------------------------------------------------------------
// EnvForceSwRendering
// ---------------------------------------------------------------------------
//    
void CAlfAppSrvSession::EnvForceSwRendering(const RMessage2& aMessage)
    {
    TBool enabled = aMessage.Int0();
    TInt err = AlfAppUi()->ForceSwRendering( enabled );
    aMessage.Complete( err );
    }

// ---------------------------------------------------------------------------
// EnvGetSizeAndRotation
// ---------------------------------------------------------------------------
//    
void CAlfAppSrvSession::EnvGetSizeAndRotation(const RMessage2& aMessage)
    {
    TPckgBuf<TSize> size;
    TPckgBuf<TInt> rotation;
    TInt err = AlfAppUi()->GetSizeAndRotation(size(), rotation());
    if ( err == KErrNone )
        {
        aMessage.Write(0, size);
        aMessage.Write(1, rotation);
        }
    aMessage.Complete( err );
    }

// ---------------------------------------------------------------------------
// EnvReadPixels
// ---------------------------------------------------------------------------
//    
void CAlfAppSrvSession::EnvReadPixels(const RMessage2& aMessage)
    {
    TInt bitmapHandle = aMessage.Int0();
    CFbsBitmap* bmp = new CFbsBitmap;
    TInt err = KErrNoMemory;

    if ( bmp )
        {
        err = bmp->Duplicate( bitmapHandle );
        if ( err == KErrNone )
            {
            err = AlfAppUi()->ReadPixels( bmp );
            }        
        delete bmp;
        }
    
    aMessage.Complete( err );
    }

void CAlfAppSrvSession::TextureCleanAnimation(const RMessage2& aMessage)
    {
    TInt id = aMessage.Int0();
    CHuiGifAnimationTexture* tex = NULL;
    for (TInt index = 0; index < iAnimatedTextures.Count(); index++)
        {
        tex = iAnimatedTextures.operator[](index);
        if (tex->Id() == id)
            {
            tex->DeleteAnimatedTexture();
            break;
            }
        }
    aMessage.Complete( KErrNone );    
    }

// ---------------------------------------------------------------------------
// ShouldReleaseGpuMemoryL
// ---------------------------------------------------------------------------
//    
TBool CAlfAppSrvSession::ShouldReleaseGpuMemoryL(MHuiBitmapProvider& aProvider, TInt aId)
    {
    // Estimate GPU RAM requirement. If higher than threshold, memory should be released.
    CFbsBitmap* bitmap = NULL;
    CFbsBitmap* mask = NULL;

    // ProvideBitmapL will handle bitmap & mask clean up (if it leaves).
    aProvider.ProvideBitmapL(aId, bitmap, mask);
    
    // Calculate estimated memory consumption.
    TInt estimatedMemoryConsumption = 0;
    
    if ( bitmap )
        {
        TSize bitmapSize = bitmap->SizeInPixels();
    
        if ( mask )
            {
            estimatedMemoryConsumption += bitmapSize.iWidth * bitmapSize.iHeight * 4;
            }
        else
            {
            switch ( bitmap->DisplayMode() )
                {
            case EGray256:
                estimatedMemoryConsumption += bitmapSize.iWidth * bitmapSize.iHeight;
                break;
                
            case EColor64K:
                estimatedMemoryConsumption += bitmapSize.iWidth * bitmapSize.iHeight * 2;
                break;
                        
            default:
                estimatedMemoryConsumption += bitmapSize.iWidth * bitmapSize.iHeight * 4;
                break;
                }
            }
        }
    
    // Delete bitmap & mask.
    delete bitmap;
    delete mask;
    
    return estimatedMemoryConsumption >= KAlfReleaseMemoryThresholdInBytes;
    }

// ---------------------------------------------------------------------------
// ReleaseOptionalGpuMemory
// ---------------------------------------------------------------------------
//    
void CAlfAppSrvSession::ReleaseOptionalGpuMemory()
    {
    // Release optional GPU memory (mainly caches).
    AlfAppUi()->ReleaseOptionalGpuMemory();
    }

// End of file    
