diff -r 000000000000 -r 4e1aa6a622a0 mediator/src/Client/MediatorNotificationsBody.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mediator/src/Client/MediatorNotificationsBody.cpp Tue Feb 02 00:53:00 2010 +0200 @@ -0,0 +1,484 @@ +/* +* 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 for receiving command/event notifications and info. +* +*/ + + +// INCLUDE FILES +#include +#include "MediatorNotificationsBody.h" +#include "MediatorServerClient.h" +#include "Debug.h" + + +// CONSTANTS +const TInt KMediatorDefaultCommandCount = 10; +const TInt KMediatorDefaultEventCount = 10; + +// ============================ MEMBER FUNCTIONS =============================== + +CMediatorNotificationsBody::CMediatorNotificationsBody() + : CActive( EPriorityNormal ), + iCommandArrayPtr(NULL, 0), + iEventArrayPtr(NULL, 0), + iCategoryBuffer( iCategory ), + iNotificationTypeBuffer( iNotificationType ), + iDestroyed(NULL) + + { + } + +void CMediatorNotificationsBody::ConstructL() + { + LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::ConstructL\n")); + CActiveScheduler::Add( this ); + User::LeaveIfError( iMediatorServer.Connect() ); + } + +CMediatorNotificationsBody* CMediatorNotificationsBody::NewL() + { + CMediatorNotificationsBody* self = new( ELeave ) CMediatorNotificationsBody; + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +CMediatorNotificationsBody::~CMediatorNotificationsBody() + { + Cancel(); + iMediatorServer.Close(); + iEventList.Close(); + iCommandList.Close(); + + if ( iDestroyed ) // RunL is being executed + { + *iDestroyed = ETrue; + } + } + +// ----------------------------------------------------------------------------- +// CMediatorNotificationsBody::RunL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorNotificationsBody::RunL() + { + TRACE(Print(_L("[Mediator Server]\t CMediatorNotificationsBody::RunL status %d\n"), iStatus.Int() )); + + if ( iStatus < 0 ) // We have an error + { + ERROR_TRACE(Print(_L("[Mediator] CMediatorNotificationsBody::RunL: iStatus=%d\n"), iStatus.Int() ) ); + + // Cleanup and return + iCommandList.Reset(); + iEventList.Reset(); + return; + } + + // 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 is set individually in each case in order to prevent erros if a leave occurs + + TInt err = KErrNone; + + // Act according to notification type. NOTE! All the observer callback-calls are trapped because + // leave would cause a possible access violation in destructor (iDestoryed pointing to an non-existing variable) + switch( iNotificationType ) + { + case EMediatorEventsRegistered: + { + LOG(_L("[Mediator Server]\t Events registered\n")); + if ( iObserver ) + { + TBool fetchEvents = iStatus.Int() > iEventList.Count() ? ETrue : EFalse; + + ResizeEventListL( iStatus.Int() ); + + if ( fetchEvents ) + { + FetchEventListL(); + } + + iDestroyed = &destroyed; + TRAP( err, iObserver->MediatorEventsAddedL( iCategory.iDomain, + iCategory.iCategory, + iEventList ) ); + } + break; + } + case EMediatorCommandsRegistered: + { + LOG(_L("[Mediator Server]\t Commands registered\n")); + if ( iObserver ) + { + TBool fetchCommands = iStatus.Int() > iCommandList.Count() ? ETrue : EFalse; + + ResizeCommandListL( iStatus.Int() ); + + if ( fetchCommands ) + { + FetchCommandListL(); + } + + iDestroyed = &destroyed; + TRAP( err, iObserver->MediatorCommandsAddedL( iCategory.iDomain, + iCategory.iCategory, + iCommandList ) ); + } + break; + } + case EMediatorEventsUnregistered: + { + LOG(_L("[Mediator Server]\t Events unregistered\n")); + if ( iObserver ) + { + TBool fetchEvents = iStatus.Int() > iEventList.Count() ? ETrue : EFalse; + + ResizeEventListL( iStatus.Int() ); + + if ( fetchEvents ) + { + FetchEventListL(); + } + + iDestroyed = &destroyed; + TRAP( err, iObserver->MediatorEventsRemovedL( iCategory.iDomain, + iCategory.iCategory, + iEventList ) ); + } + break; + } + case EMediatorCommandsUnregistered: + { + LOG(_L("[Mediator Server]\t Commands unregistered\n")); + if ( iObserver ) + { + TBool fetchCommands = iStatus.Int() > iCommandList.Count() ? ETrue : EFalse; + + ResizeCommandListL( iStatus.Int() ); + + if ( fetchCommands ) + { + FetchCommandListL(); + } + + iDestroyed = &destroyed; + TRAP( err, iObserver->MediatorCommandsRemovedL( iCategory.iDomain, + iCategory.iCategory, + iCommandList ) ); + } + break; + } + case EMediatorCategoryUnregistered: + { + + LOG(_L("[Mediator Server]\t Category unregistered\n")); + if ( iObserver ) + { + iDestroyed = &destroyed; + TRAP( err, iObserver->MediatorCategoryRemovedL( iCategory.iDomain, + iCategory.iCategory ) ); + } + break; + } + default: + { + LOG(_L("[Mediator Server]\t Unknown notification\n")); + break; + } + } + + + if ( err != KErrNone ) + { + ERROR_TRACE(Print(_L("[Mediator] CMediatorNotificationsBody::RunL: err=%d, iNotificationType=%d\n"), err, + iNotificationType ) ); + if ( !destroyed ) + { + iDestroyed = NULL; + } + + User::Leave( err ); // leave now, if an observer callback caused an error + } + + if ( !destroyed ) // client may delete instance in observer callback + { + iDestroyed = NULL; // set to NULL, because local variable goes out of scope soon + // Continue receiving notifications + ReceiveNotificationsL(); + } + + } + +// ----------------------------------------------------------------------------- +// CMediatorNotificationsBody::DoCancel +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorNotificationsBody::DoCancel() + { + LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::DoCancel\n")); + iMediatorServer.Cancel(); + } + +// ----------------------------------------------------------------------------- +// CMediatorNotificationsBody::RegisterNotificationObserver +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CMediatorNotificationsBody::RegisterNotificationObserver( + MMediatorNotifications* aObserver ) + { + iObserver = aObserver; + //return ReceiveNotifications(); + + TRAPD ( err, ReceiveNotificationsL() ); + + return err; + } + +// ----------------------------------------------------------------------------- +// CMediatorNotificationsBody::UnregisterNotificationObserver +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CMediatorNotificationsBody::UnregisterNotificationObserver() + { + iObserver = NULL; + // Empty existing arrays + if ( iCommandList.Count() > 0 ) + { + iCommandList.Reset(); + } + if ( iEventList.Count() > 0 ) + { + iEventList.Reset(); + } + // Cancel the show + return iMediatorServer.CancelNotifications(); + } + +// ----------------------------------------------------------------------------- +// CMediatorNotificationsBody::GetDomains +// Gets a list of registered domains +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CMediatorNotificationsBody::GetDomains( RDomainList& aDomains ) + { + LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::GetDomains\n")); + return iMediatorServer.GetDomains( aDomains ); + } + + +// ----------------------------------------------------------------------------- +// CMediatorNotificationsBody::GetCategories +// Gets a list of registered domains +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CMediatorNotificationsBody::GetCategories( TUid aDomain, + RCategoryList& aCategories ) + { + LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::GetCategories\n")); + return iMediatorServer.GetCategories( aDomain, aCategories ); + } + +// ----------------------------------------------------------------------------- +// CMediatorNotificationsBody::GetEvents +// Gets a list of registered events withing the domain/category +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CMediatorNotificationsBody::GetEvents( TUid aDomain, + TUid aCategory, + REventList& aEvents ) + { + LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::GetEvents\n")); + return iMediatorServer.GetEvents( aDomain, aCategory, aEvents ); + } + +// ----------------------------------------------------------------------------- +// CMediatorNotificationsBody::GetCommands +// Gets a list of registered commands withing the domain/category +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CMediatorNotificationsBody::GetCommands( TUid aDomain, + TUid aCategory, + RCommandList& aCommands ) + { + LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::GetCommands\n")); + return iMediatorServer.GetCommands( aDomain, aCategory, aCommands ); + } + + +// ----------------------------------------------------------------------------- +// CMediatorNotificationsBody::ReceiveNotificationsL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// + +void CMediatorNotificationsBody::ReceiveNotificationsL() + { + LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::ReceiveNotificationsL\n")); + if ( IsActive() ) + { + ERROR_LOG(_L("[Mediator] CMediatorNotificationsBody::ReceiveNotificationsL: User::Leave( KErrAlreadyExists )\n") ); + User::Leave( KErrAlreadyExists ); + } + + ResizeEventListL( KMediatorDefaultEventCount ); + + ResizeCommandListL ( KMediatorDefaultCommandCount ); + + // Define data return pointers + TInt commandArraySize = ( sizeof(MediatorService::TCommand) ) * KMediatorDefaultCommandCount; + TPtr8 commandArrayPtr( (TUint8*)&iCommandList[0], commandArraySize ); + iCommandArrayPtr.Set( commandArrayPtr ); + + TInt eventArraySize = ( sizeof(MediatorService::TEvent) ) * KMediatorDefaultEventCount; + TPtr8 eventArrayPtr( (TUint8*)&iEventList[0], eventArraySize ); + iEventArrayPtr.Set( eventArrayPtr ); + + SetActive(); + + iMediatorServer.ReceiveNotifications( iStatus, + iCategoryBuffer, + iNotificationTypeBuffer, + iEventArrayPtr, + iCommandArrayPtr ); + } + +// ----------------------------------------------------------------------------- +// CMediatorNotificationsBody::ResizeEventListL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorNotificationsBody::ResizeEventListL( TInt aEventCount ) + { + LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::ResizeEventListL\n")); + if ( iEventList.Count() > aEventCount ) // less events has been received than space allocated + { + // suppress list + for ( TInt i = iEventList.Count() - 1; i >= aEventCount; i-- ) + { + iEventList.Remove( i ); + } + } + else if ( iEventList.Count() < aEventCount ) // more events than initially/previously allocated + { + // reallocate event list + iEventList.Reset(); + + User::LeaveIfError( iEventList.Reserve( aEventCount ) ); + + for ( TInt i = 0; i < aEventCount; i++ ) + { + TEvent emptyEvent; + iEventList.Append( emptyEvent ); + } + } + } + +// ----------------------------------------------------------------------------- +// CMediatorNotificationsBody::ResizeCommandListL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorNotificationsBody::ResizeCommandListL( TInt aCommandCount ) + { + LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::ResizeCommandListL\n")); + if ( iCommandList.Count() > aCommandCount ) // less commands has been received than space allocated + { + // suppress list + for ( TInt i = iCommandList.Count() - 1; i >= aCommandCount; i-- ) + { + iCommandList.Remove( i ); + } + } + else if ( iCommandList.Count() < aCommandCount ) // more commands than initially/previously allocated + { + // reallocate command list + iCommandList.Reset(); + + User::LeaveIfError( iCommandList.Reserve( aCommandCount) ); + + for ( TInt i = 0; i < aCommandCount; i++ ) + { + TCommand emptyCommand; + iCommandList.Append( emptyCommand ); + } + } + } + +// ----------------------------------------------------------------------------- +// CMediatorNotificationsBody::FetchEventListL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorNotificationsBody::FetchEventListL() + { + LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::FetchEventListL\n")); + TInt eventArraySize = ( sizeof(MediatorService::TEvent) ) * iEventList.Count(); + TPtr8 eventArrayPtr( (TUint8*)&iEventList[0], eventArraySize ); + iEventArrayPtr.Set( eventArrayPtr ); + User::LeaveIfError( iMediatorServer.FetchNotificationEventList( iEventArrayPtr ) ); + } + +// ----------------------------------------------------------------------------- +// CMediatorNotificationsBody::FetchCommandListL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorNotificationsBody::FetchCommandListL() + { + LOG(_L("[Mediator Server]\t CMediatorNotificationsBody::FetchCommandListL\n")); + TInt commandArraySize = ( sizeof(MediatorService::TCommand) ) * iCommandList.Count(); + TPtr8 commandArrayPtr( (TUint8*)&iCommandList[0], commandArraySize ); + iCommandArrayPtr.Set( commandArrayPtr ); + User::LeaveIfError( iMediatorServer.FetchNotificationCommandList( commandArrayPtr ) ); + } + +// ---------------------------------------------------------------------------- +// CStartupMediatorPluginSubscriber::RunError() +// ---------------------------------------------------------------------------- +#ifdef _DEBUG +TInt CMediatorNotificationsBody::RunError( TInt aError ) +#else +TInt CMediatorNotificationsBody::RunError( TInt /*aError*/ ) +#endif //_DEBUG + { + ERROR_TRACE(Print(_L("[Mediator] CMediatorNotificationsBody::RunError: err=%d\n"), aError)); + + // Return KErrNone to avoid panic + return KErrNone; + } + +// End of File