mediator/src/Client/MediatorEventConsumerBody.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 00:53:00 +0200
changeset 0 4e1aa6a622a0
child 10 1fc153c72b60
permissions -rw-r--r--
Revision: 201003

/*
* Copyright (c) 2005 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:  An implementation class for receiving Mediator events.
*
*/


// INCLUDE FILES
#include    <e32base.h>
#include    "MediatorEventConsumerBody.h"
#include    "MediatorServerClient.h"
#include    "Debug.h"


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

CMediatorEventConsumerBody::CMediatorEventConsumerBody( MMediatorEventObserver* aObserver )
    : CActive( EPriorityNormal ),
      iObserver( aObserver ), 
      iCategoryBuffer( iCategory ),
      iEventBuffer( iEvent ),
      iEventDataPtr( NULL, 0 ),
      iDestroyed ( NULL )
    {
    }

void CMediatorEventConsumerBody::ConstructL()
    {
    CActiveScheduler::Add( this );
    User::LeaveIfError( iMediatorServer.Connect() );
    ResetDataBufferL( KMaxEventData );  
    }

CMediatorEventConsumerBody* CMediatorEventConsumerBody::NewL(
                        MMediatorEventObserver* aObserver )
    {
    CMediatorEventConsumerBody* self = new( ELeave ) CMediatorEventConsumerBody( aObserver );
    
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );

    return self;
    }
    
CMediatorEventConsumerBody::~CMediatorEventConsumerBody()
    {
    Cancel();
    iMediatorServer.Close();
    delete iEventData;
    
    if ( iDestroyed ) // RunL is being executed
        {
        *iDestroyed = ETrue;
        }
    }

// -----------------------------------------------------------------------------
// CMediatorEventConsumerBody::RunL
//  
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMediatorEventConsumerBody::RunL()
    {
    TRACE(Print(_L("[Mediator Server]\t CMediatorEventConsumerBody::RunL status %d\n"), iStatus.Int() ));
    
    if ( iObserver && ( iStatus >= KErrNone ) )
        {
        // Check the parameter data size. If bigger than expected, fetch it synchronously
        TInt dataSize = iStatus.Int();
        if ( dataSize > iEventDataPtr.MaxLength() )
            {
            // Reset data buffer for bigger size
            ResetDataBufferL( dataSize );
            
            // Fetch data from Mediator
            iMediatorServer.FetchParameterData( iEventDataPtr );
            }
        
        // Set the flag to the member variable that is updated by the destructor 
        // in case this instance is destroyed by observer callback.
        // Otherwise an attempt to manipulate member data after destruction will cause a panic.
        TBool destroyed = EFalse;
        iDestroyed = &destroyed;
        
        // must be trapped, so that leave won't cause access violation (iDestroyed pointing to a non-existing variable)
        TRAPD( err, iObserver->MediatorEventL( iCategory.iDomain,
                                               iCategory.iCategory, 
                                               iEvent.iEventId, 
                                               *iEventData ) );
        
        if ( err != KErrNone )
            {
            ERROR_TRACE(Print(_L("[Mediator] CMediatorEventConsumerBody::RunL: err=%d\n"), err ) );
            if ( !destroyed )
                {
                iDestroyed = NULL;
                }
            User::Leave( err );
            }
        
        if ( destroyed )
            {
            return; // instance destroyed in MediatorEventL, don't proceed to event receiving
            }
        
        iDestroyed = NULL; // set member variable to NULL, because local variable goes out of scope            
        }
    StartEventReceiving();
    }
        
// -----------------------------------------------------------------------------
// CMediatorEventConsumerBody::DoCancel
//  
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMediatorEventConsumerBody::DoCancel()
    {
    LOG(_L("[Mediator Server]\t CMediatorEventConsumerBody::DoCancel\n")); 
    iMediatorServer.Cancel();    
    }

// -----------------------------------------------------------------------------
// CMediatorEventConsumerBody::SubscribeEventL
// Subscribe to event category
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CMediatorEventConsumerBody::SubscribeEvent( TUid aDomain,
                                                      TUid aCategory,
                                                      const REventList& aEvents )
    {
    LOG(_L("[Mediator Server]\t CMediatorEventConsumerBody::SubscribeEvent\n"));
    // Start to receive
    StartEventReceiving();
    // Subscribe
    return iMediatorServer.SubscribeEventList( aDomain, 
                                               aCategory,
                                               aEvents );
    }
    
// -----------------------------------------------------------------------------
// CMediatorEventConsumerBody::SubscribeEventL
// Subscribe to event
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CMediatorEventConsumerBody::SubscribeEvent( TUid aDomain,
                                                      TUid aCategory, 
                                                      TInt aEventId,
                                                      TVersion aVersion )
    {
    LOG(_L("[Mediator Server]\t CMediatorEventConsumerBody::SubscribeEvent\n"));
    
    __UHEAP_MARK;
        
    // Create a list to contain one event
    REventList eventList;
    TEvent event;
    event.iEventId = aEventId;
    event.iVersion = aVersion;
    TInt error = eventList.Append( event );
        
    if ( !error )
        {
        // Start to receive
        StartEventReceiving();
        // Subscribe eventlist
        error = iMediatorServer.SubscribeEventList( aDomain,
                                                    aCategory,
                                                    eventList );
        }
    else
        {
        ERROR_TRACE(Print(_L("[Mediator] CMediatorEventConsumerBody::SubscribeEvent: error=%d\n"), error ) );
        }
        
    // Clean up                                        
    eventList.Reset();
    
    __UHEAP_MARKEND;
    return error;
    }
    
// -----------------------------------------------------------------------------
// CMediatorEventConsumerBody::UnsubscribeEvent
// Unsubscibe an event category.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CMediatorEventConsumerBody::UnsubscribeEvent( TUid aDomain,
                                                        TUid aCategory,
                                                        const REventList& aEvents )
    {
    LOG(_L("[Mediator Server]\t CMediatorEventConsumerBody::UnsubscribeEvent list\n"));
    return iMediatorServer.UnsubscribeEventList( aDomain, aCategory, aEvents );
    }
    
// -----------------------------------------------------------------------------
// CMediatorEventConsumerBody::UnsubscribeEvent
// Unsubscibe an event.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CMediatorEventConsumerBody::UnsubscribeEvent( TUid aDomain,
                                                        TUid aCategory, 
                                                        TInt aEventId )
    {
    LOG(_L("[Mediator Server]\t CMediatorEventConsumerBody::UnsubscribeEvent\n"));
    __UHEAP_MARK;
    
    // Create a list to contain one event
    REventList eventList;
    TEvent event;
    event.iEventId = aEventId;
    TInt error = eventList.Append( event );
        
    if ( !error )
        {
        // Unsubscribe eventlist
        error = iMediatorServer.UnsubscribeEventList( aDomain,
                                                      aCategory,
                                                      eventList );
        }
    else
        {
        ERROR_TRACE(Print(_L("[Mediator] CMediatorEventConsumerBody::UnsubscribeEvent: error=%d\n"), error ) );
        }        
        
    // Clean up                                        
    eventList.Reset();
    
    __UHEAP_MARKEND;
    return error;
    }

// -----------------------------------------------------------------------------
// CMediatorEventConsumerBody::StartEventReceiving
// Starts to wait for events
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//    
void CMediatorEventConsumerBody::StartEventReceiving()
    {
	if ( !IsActive() )
	    {
	    iMediatorServer.ReceiveEvents( iStatus, 
	                                   iCategoryBuffer, 
	                                   iEventBuffer, 
	                                   iEventDataPtr );
        SetActive();	                                   
	    }
    }

// -----------------------------------------------------------------------------
// CMediatorEventConsumerBody::ResetDataBufferL
// Starts to receive commands asynchronously
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//    
void CMediatorEventConsumerBody::ResetDataBufferL( TInt aSize )
    {
    if ( iEventData )
        {
        delete iEventData;
        iEventData = NULL;
        }
    iEventData = HBufC8::NewL( aSize );
    iEventDataPtr.Set( iEventData->Des() );
       
    }
//  End of File