satengine/SatServer/Engine/src/CSatSSession.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:11:09 +0200
changeset 0 ff3b6d0fd310
permissions -rw-r--r--
Revision: 201003 Kit: 201005

/*
* Copyright (c) 2002-2009 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:  The Sat Server session manages a connection to a client and
*                handles client requests.
*
*/


#include    <fbs.h>
#include    "MSatUtils.h"
#include    "CSatIconHandler.h"
#include    "CSatSSession.h"
#include    "CSatSUiSubSession.h"
#include    "CSatSServer.h"
#include    "EnginePanic.h"
#include    "SatLog.h"
#include    "TSatEventMediator.h"
#include    "SatSOpcodes.h"
#include    "MSatApi.h"
#include    "MSatUtils.h"
#include    "CSatSRefreshSubSession.h"
#include    "MThreadDeathNotifier.h"
#include    "CSatSIconSubSession.h"

const TUint8 KHandleParam( 3 );

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

// -----------------------------------------------------------------------------
// Class constructor
// -----------------------------------------------------------------------------
//
CSatSSession::CSatSSession(
    CSatSServer* aServer,
    TSatEventMediator& aEventMediator,
    MSatApi& aSatApi,
    MThreadDeathNotifier& aThreadDeathNotifier ) :
    CSession2(),
    iSatServer( aServer ),
    iEventMediator( aEventMediator ),
    iSatApi( aSatApi ),
    iThreadDeathNotifier( aThreadDeathNotifier )
    {
    LOG( SIMPLE, "SATENGINE: CSatSSession::CSatSSession calling-exiting" )
    }

// -----------------------------------------------------------------------------
// Two-phased constructor
// -----------------------------------------------------------------------------
//
CSatSSession* CSatSSession::NewL(
    CSatSServer* aServer,
    TSatEventMediator& aEventMediator,
    MSatApi& aSatApi,
    MThreadDeathNotifier& aThreadDeathNotifier )
    {
    LOG( SIMPLE, "SATENGINE: CSatSSession::NewL calling" )

    // Perform construction.
    CSatSSession* self =
        new ( ELeave ) CSatSSession(
            aServer,
            aEventMediator,
            aSatApi,
            aThreadDeathNotifier );

    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );

    LOG( SIMPLE, "SATENGINE: CSatSSession::NewL exiting" )
    return self;
    }

// -----------------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------------
//
CSatSSession::~CSatSSession()
    {
    LOG( SIMPLE, "SATENGINE: CSatSSession::~CSatSSession calling" )

    delete iSubSessionIx;
    delete iSubSessionCon;

    iSatServer = NULL;
    iUiSubSession = NULL;

    LOG( SIMPLE, "SATENGINE: CSatSSession::~CSatSSession exiting" )
    }

// -----------------------------------------------------------------------------
// CSatSSession::ConstructL
// -----------------------------------------------------------------------------
//
void CSatSSession::ConstructL()
    {
    LOG( SIMPLE, "SATENGINE: CSatSSession::ConstructL calling" )

    iSubSessionCon = iSatServer->CreateNewContainerL();
    iSubSessionIx = CObjectIx::NewL();

    LOG( SIMPLE, "SATENGINE: CSatSSession::ConstructL exiting" )
    }

// -----------------------------------------------------------------------------
// CSatSSession::UiSubSession
// -----------------------------------------------------------------------------
//
MSatUiSession* CSatSSession::UiSubSession()
    {
    LOG( DETAILED, "SATENGINE: CSatSSession::UiSubSession calling" )

    MSatUiSession* session = iUiSubSession;

    LOG( DETAILED, "SATENGINE: CSatSSession::UiSubSession exiting" )
    return session;
    }

// -----------------------------------------------------------------------------
// CSatSSession::CloseSubSession
// -----------------------------------------------------------------------------
TBool CSatSSession::CloseSubSession( const RMessage2& aMessage )
    {
    LOG( SIMPLE, "SATENGINE: CSatSSession::CloseSubSession calling" )

    // If subssession exists, return TRUE. Otherwise, return FALSE
    TInt result = ETrue;
    // Read the handle from client.
    const TInt handle( aMessage.Int3() );

    // Check that subsession exists before deleting the subsession
    if ( iSubSessionIx->At( handle ) )
        {
        LOG(
        SIMPLE, "SATENGINE: CSatSSession::CloseSubSession subsession exists" )
        // Delete the sub-session.
        iSubSessionIx->Remove( handle );
        }
    else
        {
        LOG( SIMPLE, 
        "SATENGINE: CSatSSession::CloseSubSession subsession doesn't exist" )
        // Sub-session handle was not valid.
        PanicClient( aMessage, ESatSBadDescriptor );
        result = EFalse;
        }

    LOG( SIMPLE, "SATENGINE: CSatSSession::CloseSubSession exiting" )
    return result;
    }

// -----------------------------------------------------------------------------
// CSatSSession::GetSubSessionFromHandle
// Returns the subsession which handle is aHandle.
// -----------------------------------------------------------------------------
CSatSSubSession* CSatSSession::GetSubSessionFromHandle( TInt aHandle ) const
    {
    LOG( DETAILED, "SATENGINE: CSatSSession::GetSubSessionFromHandle calling" )

    CSatSSubSession* session =
        static_cast<CSatSSubSession*>( iSubSessionIx->At( aHandle ) );

    LOG( DETAILED, "SATENGINE: CSatSSession::GetSubSessionFromHandle exiting" )
    return session;
    }

// -----------------------------------------------------------------------------
// CSatSSession::AddSubSessionL
// -----------------------------------------------------------------------------
void CSatSSession::AddSubSessionL(
    CSatSSubSession* aSubSession,
    const RMessage2& aMessage )
    {
    LOG( SIMPLE, "SATENGINE: CSatSSession::AddSubSessionL calling" )

    __ASSERT_ALWAYS( aSubSession, PanicSatEngine( ESatEngineNullPointer ) );

    CleanupStack::PushL( aSubSession );
    iSubSessionCon->AddL( aSubSession );
    const TInt handle( iSubSessionIx->AddL( aSubSession ) );
    CleanupStack::Pop( aSubSession );

    // Send the handle to client.
    TPckg<TInt> handlePckg( handle );
    TRAPD( err, aMessage.WriteL( KHandleParam, handlePckg ) );

    if ( KErrNone != err )
        {
        // Remove the handle, will also cause destruction
        // of session.
        iSubSessionIx->Remove( handle );
        LOG2( SIMPLE, 
        "SATENGINE: CSatSSession::AddSubSessionL panic: %i", err )
        PanicClient( aMessage, ESatSBadDescriptor );
        User::Leave( err ); 
        }

    LOG( SIMPLE, "SATENGINE: CSatSSession::AddSubSessionL exiting" )
    }

// -----------------------------------------------------------------------------
// CSatSSession::ServiceL
// Dispatches the commands to their appropriate handlers. For asynchronous
// messages, the message object is save for future processing.
// -----------------------------------------------------------------------------
//
void CSatSSession::ServiceL( const RMessage2& aMessage )
    {
    LOG( SIMPLE, "SATENGINE: CSatSSession::ServiceL calling" )

    if ( !aMessage.HasCapability( ECapabilityReadDeviceData ) )
        {
        // Legal client should at least have ReadDeviceData capability
        LOG( SIMPLE, "SATENGINE: CSatSSession::ServiceL client \
        has no ReadDeviceData capability. Panic it" )
        PanicClient( aMessage, ESatSBadDescriptor );
        }
    else
        {
        // Client has enough capability
        
        LOG2( NORMAL, "SATENGINE: CSatSSession::ServiceL \
              aMessage.Function is %d", aMessage.Function() )

        switch ( aMessage.Function() )
            {
            //  Ui Sub-session indicator.
            case ESatSOpenUiSubSession:
                {
                LOG( SIMPLE, 
                "SATENGINE: CSatSSession::ServiceL ESatSOpenUiSubSession" )
                CSatSUiSubSession* subsession = CSatSUiSubSession::NewL(
                    *this,
                    iSatApi,
                    iEventMediator );

                TRAPD( err, AddSubSessionL( subsession, aMessage ) );
                if ( KErrNone == err )
                    {
                    // Store the ui clients thread handle.
                    RThread uiClientThread;
                    User::LeaveIfError( aMessage.Client( uiClientThread ) );

                    iUiSubSession = subsession;

                    // Start observing threads state
                    TThreadId threadId = uiClientThread.Id();
                    iThreadDeathNotifier.SetObserveredThread( threadId );
                    iThreadDeathNotifier.StartObservingThread();
                    uiClientThread.Close();

                    // Complete message before notifying SAT Server since notifying may
                    // be very time consuming operation dependening on the situation
                    aMessage.Complete( KErrNone );

                    // Event has to be send after the iUiSubSession has been set.
                    // Otherwise NULL pointer error in commandhandlers.
                    iEventMediator.Notify( MSatUtils::ESatUiLaunched );
                    }
                break;
                }

            case ESatSOpenRefreshSubSession:
                {
                LOG( SIMPLE, 
                "SATENGINE: CSatSSession::ServiceL ESatSOpenRefreshSubSession" )
                CSatSRefreshSubSession* subsession = CSatSRefreshSubSession::NewL(
                    *this,
                    iEventMediator );
                
                TRAPD( err, AddSubSessionL( subsession, aMessage ) );
                if ( KErrNone == err )
                    {
                    aMessage.Complete( KErrNone );
                    }
                break;
                }

            case ESatSOpenIconSubSession:
                {
                LOG( SIMPLE, 
                "SATENGINE: CSatSSession::ServiceL ESatSOpenIconSubSession" )
                CSatSIconSubSession* subsession = CSatSIconSubSession::NewL(
                    *this,
                    iEventMediator );

                TRAPD( err, AddSubSessionL( subsession, aMessage ) );
                if ( KErrNone == err )
                    {
                    aMessage.Complete( KErrNone );
                    }
                break;
                }

            case ESatSCloseUiSubSession:
                {
                LOG( SIMPLE, 
                "SATENGINE: CSatSSession::ServiceL ESatSCloseUiSubSession" )
                iEventMediator.Notify( MSatUtils::ESatUiClosed );
                iSatUiSubSessionClosed = ETrue;
                iUiSubSession = NULL;
                if ( CloseSubSession( aMessage ) )
                    {
                    aMessage.Complete( KErrNone );
                    }
                break;
                }

            case ESatSCloseRefreshSubSession:
                {
                LOG( SIMPLE, 
                "SATENGINE: CSatSSession::ServiceL ESatSCloseRefreshSubSession" )
                if ( CloseSubSession( aMessage ) )
                    {
                    aMessage.Complete( KErrNone );
                    }
                break;
                }

            case ESatSCloseIconSubSession:
                {
                LOG( SIMPLE, 
                "SATENGINE: CSatSSession::ServiceL ESatSCloseIconSubSession" )
                if ( CloseSubSession( aMessage ) )
                    {
                    aMessage.Complete( KErrNone );
                    }
                break;
                }

            default:
                {
                LOG( SIMPLE, "SATENGINE: CSatSSession::ServiceL others" )
                CSatSSubSession* subsession =
                    GetSubSessionFromHandle( aMessage.Int3() );

                if ( NULL != subsession )
                    {
                    LOG( SIMPLE, 
                    "SATENGINE: CSatSSession::ServiceL NULL != subsession" )
                    subsession->HandleCommandL( aMessage );
                    }
                else
                    {
                    PanicClient( aMessage, ESatSBadDescriptor );
                    }
                }
            }
        }
        LOG( SIMPLE, "SATENGINE: CSatSSession::ServiceL exiting" )
    }

// -----------------------------------------------------------------------------
// CSatSSession::PanicClient
// Panics the client.
// -----------------------------------------------------------------------------
//
void CSatSSession::PanicClient( const RMessage2& aMessage, TInt aPanic ) const
    {
    LOG( SIMPLE, "SATENGINE: CSatSSession::PanicClient calling" )

    _LIT( KTxtServer, "SatS server" );
    aMessage.Panic( KTxtServer, aPanic );

    LOG( SIMPLE, "SATENGINE: CSatSSession::PanicClient exiting" )
    }

// -----------------------------------------------------------------------------
// CSatSSession::NotifyThreadDeathMonitor
// Notifies ThreadDeathMonitor for thread is dying
// -----------------------------------------------------------------------------
//
void CSatSSession::NotifyThreadDeathMonitor()
    {
    LOG( SIMPLE, "SATENGINE: CSatSSession::NotifyThreadDeathMonitor calling" )

    iThreadDeathNotifier.NotifyThreadDeath();

    LOG( SIMPLE, "SATENGINE: CSatSSession::NotifyThreadDeathMonitor exiting" )
    }

// -----------------------------------------------------------------------------
// CSatSSession::SatServer
// Returns pointer to SatServer - class
// -----------------------------------------------------------------------------
//
CSatSServer* CSatSSession::SatServer()
    {
    LOG( SIMPLE, "SATENGINE: CSatSSession::SatServer calling-exiting" )
    return iSatServer;
    }

// -----------------------------------------------------------------------------
// CSatSSession::UiSessionClosed
// Notifies SatEngine that UI session has closed
// -----------------------------------------------------------------------------
//
void CSatSSession::UiSessionClosed()
    {
    LOG( SIMPLE, "SATENGINE: CSatSSession::UiSessionClosed calling" )

    if ( !iSatUiSubSessionClosed )
        {
        LOG( SIMPLE, "SATENGINE: CSatSSession::UiSessionClosed close satui" )
        iEventMediator.Notify( MSatUtils::ESatUiClosed );
        iSatUiSubSessionClosed = ETrue;
        }

    LOG( SIMPLE, "SATENGINE: CSatSSession::UiSessionClosed exiting" )
    }

// -----------------------------------------------------------------------------
// CSatSSession::CreateIconHandlerL
// Creates and returns CSatIconHandler
// -----------------------------------------------------------------------------
//
MSatSIconAPI* CSatSSession::CreateIconHandlerL()
    {
    LOG( SIMPLE, "SATENGINE: CSatSSession::CreateIconHandlerL calling-exiting" )
    return new( ELeave ) CSatIconHandler( iSatApi );
    }