diff -r 000000000000 -r 95b198f216e5 omadrm/drmengine/notifier/src/DRMEventHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omadrm/drmengine/notifier/src/DRMEventHandler.cpp Thu Dec 17 08:52:27 2009 +0200 @@ -0,0 +1,982 @@ +/* +* Copyright (c) 2004 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: Implementation of class CDRMEventHandler +* +*/ + + + +// INCLUDE FILES +#include +#include "DRMEventHandler.h" +#include "drmnotifierclientserver.h" + +// EXTERNAL DATA STRUCTURES +// EXTERNAL FUNCTION PROTOTYPES +// CONSTANTS +// MACROS +// LOCAL CONSTANTS AND MACROS +// MODULE DATA STRUCTURES +// LOCAL FUNCTION PROTOTYPES +// FORWARD DECLARATIONS + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CDRMEventHandler::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CDRMEventHandler* CDRMEventHandler::NewL() + { + CDRMEventHandler* self = new( ELeave ) CDRMEventHandler; + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + + return self; + } + +// ----------------------------------------------------------------------------- +// CDRMEventHandler::~CDRMEventHandler +// Destructor. +// ----------------------------------------------------------------------------- +// +CDRMEventHandler::~CDRMEventHandler() +{ + if( iHandler ) + { + Cancel(); + } + + if( iData ) + { + delete iData; + iData = NULL; + } + if( iDataBuffer ) + { + delete iDataBuffer; + iDataBuffer = NULL; + } + if( iEventType ) + { + delete iEventType; + iEventType = NULL; + } + + if( iWaitData ) + { + delete iWaitData; + iWaitData = NULL; + } + if( iWaitDataBuffer ) + { + delete iWaitDataBuffer; + iWaitDataBuffer = NULL; + } + if( iEventTypeWait ) + { + delete iEventTypeWait; + iEventTypeWait = NULL; + } + + if ( iAddRemoveObservers ) + { + for( TInt i = 0; i < iAddRemoveObservers->Count();i++) + { + delete (*iAddRemoveObservers)[i]->iContentID; + (*iAddRemoveObservers)[i]->iContentID = NULL; + } + iAddRemoveObservers->Reset(); + delete iAddRemoveObservers; + iAddRemoveObservers = NULL; + } + if ( iModifyObservers ) + { + for( TInt i = 0; i < iModifyObservers->Count();i++) + { + delete (*iModifyObservers)[i]->iContentID; + (*iModifyObservers)[i]->iContentID = NULL; + } + iModifyObservers->Reset(); + delete iModifyObservers; + iModifyObservers = NULL; + } + + if ( iTimeChangeObservers ) + { + iTimeChangeObservers->Reset(); + delete iTimeChangeObservers; + iTimeChangeObservers = NULL; + } + + if ( iDelayedObservers ) + { + for( TInt i = 0; i < iDelayedObservers->Count();i++) + { + delete (*iDelayedObservers)[i]->iContentID; + (*iDelayedObservers)[i]->iContentID = NULL; + } + iDelayedObservers->Reset(); + delete iDelayedObservers; + iDelayedObservers = NULL; + } + + if( iHandler ) + { + iHandler->Close(); + delete iHandler; + iHandler = NULL; + } + } + + +// ----------------------------------------------------------------------------- +// CDRMEventHandler::RegisterEventObserverL +// Adds the new handler to the list of handlers. +// Checks if the handler is already in the list +// Sets the active object active if it is not active yet. +// ----------------------------------------------------------------------------- +// +void CDRMEventHandler::RegisterEventObserverL( + MDRMEventObserver& aObserver, + const TDRMEventType& aEvent ) + { + + TInt count = 0; + TBool addToServer = ETrue; + + + if( iIsDelayed ) + { + TDelayedObserverData* delayData = new (ELeave) TDelayedObserverData; + CleanupStack::PushL( delayData); + delayData->iRequest = KRegisterOperation; + delayData->iObserver = &aObserver; + delayData->iEventType = aEvent; + delayData->iContentID = NULL; + iDelayedObservers->AppendL( delayData ); + CleanupStack::Pop(); // delayData; + return; + } + + switch ( aEvent ) + { + case KEventAddRemove: + if ( iAddRemoveObservers ) + { + for ( count = 0; count < iAddRemoveObservers->Count(); ++count ) + { + if ( ( *iAddRemoveObservers )[ count ]->iObserver == &aObserver && + !( *iAddRemoveObservers )[ count ]->iContentID ) + { + return; + } + else if( addToServer && !( *iAddRemoveObservers)[ count ]->iContentID ) + { + addToServer = EFalse; + } + } + } + break; + case KEventModify: + if ( iModifyObservers ) + { + for ( count = 0; count < iModifyObservers->Count(); ++count ) + { + if ( ( *iModifyObservers )[ count ]->iObserver == &aObserver && + !( *iModifyObservers )[ count ]->iContentID ) + { + return; + } + else if( addToServer && !( *iModifyObservers)[ count ]->iContentID ) + { + addToServer = EFalse; + } + } + } + break; + case KEventTimeChange: + if ( iTimeChangeObservers ) + { + for ( count = 0; count < iTimeChangeObservers->Count(); ++count ) + { + if ( ( *iTimeChangeObservers )[ count ]->iObserver == &aObserver ) + { + return; + } + } + } + break; + default: + User::Leave(KErrArgument); + break; + } + + struct TObserverData* observer = new (ELeave) TObserverData; + CleanupStack::PushL(observer); + + observer->iObserver = &aObserver; + observer->iContentID = NULL; + + switch( aEvent ) + { + case KEventAddRemove: + iAddRemoveObservers->AppendL( observer ); + break; + case KEventModify: + iModifyObservers->AppendL( observer ); + break; + case KEventTimeChange: + iTimeChangeObservers->AppendL( observer ); + break; + default: + User::Leave(KErrArgument); + break; + } + + if ( !IsAdded() ) + { + CActiveScheduler::Add( this ); + } + + if ( !IsActive() ) + { + if( iStatus != KRequestPending ) + { + iStatus = KRequestPending; + iHandler->WaitForCompletion(iStatus); + } + SetActive(); + } + + // Register the type to the server + if( addToServer ) + { + iHandler->RegisterForType(aEvent); + } + + CleanupStack::Pop(); // observer + } + +// ----------------------------------------------------------------------------- +// CDRMEventHandler::UnRegisterEventObserverL +// Removes the observer from the list of handlers. +// ----------------------------------------------------------------------------- +// +void CDRMEventHandler::UnRegisterEventObserverL( + MDRMEventObserver& aObserver, + const TDRMEventType& aEvent) + { + TInt count = 0; + TBool removeFromServer = ETrue; + + if( iIsDelayed ) + { + TDelayedObserverData* delayData = new (ELeave) TDelayedObserverData; + CleanupStack::PushL( delayData); + delayData->iRequest = KUnRegisterOperation; + delayData->iObserver = &aObserver; + delayData->iEventType = aEvent; + delayData->iContentID = NULL; + iDelayedObservers->AppendL( delayData ); + CleanupStack::Pop(); // delayData; + return; + } + + // Check if something else uses the registration for this event type, if something + // Does set removeFromServer to EFalse so the registration is not removed from the + // server + switch ( aEvent ) + { + case KEventAddRemove: + if ( iAddRemoveObservers ) + { + for ( count = 0; count < iAddRemoveObservers->Count(); ++count ) + { + if( removeFromServer && !( *iAddRemoveObservers)[ count ]->iContentID && + ( *iAddRemoveObservers)[ count ]->iObserver != &aObserver ) + { + removeFromServer = EFalse; + } + } + } + break; + case KEventModify: + if ( iModifyObservers ) + { + for ( count = 0; count < iModifyObservers->Count(); ++count ) + { + if( removeFromServer && !( *iModifyObservers)[ count ]->iContentID && + ( *iModifyObservers)[ count ]->iObserver != &aObserver ) + { + removeFromServer = EFalse; + } + } + } + break; + case KEventTimeChange: + if ( iTimeChangeObservers ) + { + for ( count = 0; count < iTimeChangeObservers->Count(); ++count ) + { + if( ( *iTimeChangeObservers)[ count ]->iObserver != &aObserver ) + { + removeFromServer = EFalse; + } + } + } + break; + default: + User::Leave(KErrArgument); + break; + } + + + // Remove the registrations from internal lists and possibly from the server + switch ( aEvent ) + { + case KEventAddRemove: + if ( iAddRemoveObservers ) + { + for ( count = 0; count < iAddRemoveObservers->Count(); ++count ) + { + if ( ( *iAddRemoveObservers )[ count ]->iObserver == &aObserver && + !( *iAddRemoveObservers )[ count ]->iContentID ) + { + if( removeFromServer ) + { + // Unregister the type from the server + iHandler->UnRegisterFromType(aEvent); + } + + // Free Memory + delete ( *iAddRemoveObservers )[ count ]; + ( *iAddRemoveObservers )[ count ] = NULL; + + // Delete the element from the table + iAddRemoveObservers->Delete( count ); + iAddRemoveObservers->Compress(); + return; + } + } + } + User::Leave(KErrNotFound); + break; + case KEventModify: + if ( iModifyObservers ) + { + for ( count = 0; count < iModifyObservers->Count(); ++count ) + { + if ( ( *iModifyObservers )[ count ]->iObserver == &aObserver && + !( *iModifyObservers )[ count ]->iContentID ) + { + if( removeFromServer ) + { + // Unregister the type from the server + iHandler->UnRegisterFromType(aEvent); + } + + // Free Memory + delete ( *iModifyObservers )[ count ]; + ( *iModifyObservers )[ count ] = NULL; + + // Delete the element from the table + iModifyObservers->Delete( count ); + iModifyObservers->Compress(); + return; + } + } + } + User::Leave(KErrNotFound); + break; + case KEventTimeChange: + if ( iTimeChangeObservers ) + { + for ( count = 0; count < iTimeChangeObservers->Count(); ++count ) + { + if ( ( *iTimeChangeObservers )[ count ]->iObserver == &aObserver ) + { + if( removeFromServer ) + { + // Unregister the type from the server + iHandler->UnRegisterFromType(aEvent); + } + + // Free Memory + delete ( *iTimeChangeObservers )[ count ]; + ( *iTimeChangeObservers )[ count ] = NULL; + + // Delete the element from the table + iTimeChangeObservers->Delete( count ); + iTimeChangeObservers->Compress(); + return; + } + } + } + User::Leave(KErrNotFound); + break; + default: + User::Leave(KErrArgument); + break; + } + // Should never get here + User::Leave( KErrGeneral ); + } + +// ----------------------------------------------------------------------------- +// CDRMEventHandler::RegisterEventObserverL +// Adds the new handler to the list of handlers. +// Checks is the handler is already in the list +// Sets the active object active if it is not active yet. +// ----------------------------------------------------------------------------- +// +void CDRMEventHandler::RegisterEventObserverL( + MDRMEventObserver& aObserver, + const TDRMEventType& aEvent, + const TDesC8& aContentID ) + { + TInt count = 0; + TBool addToServer = ETrue; + + if( iIsDelayed ) + { + TDelayedObserverData* delayData = new (ELeave) TDelayedObserverData; + CleanupStack::PushL( delayData); + delayData->iRequest = KRegisterURIOperation; + delayData->iObserver = &aObserver; + delayData->iEventType = aEvent; + delayData->iContentID = aContentID.AllocLC(); + iDelayedObservers->AppendL( delayData ); + CleanupStack::Pop(); // iContentID; + CleanupStack::Pop(); // delayData; + return; + } + + switch ( aEvent ) + { + case KEventAddRemove: + if ( iAddRemoveObservers ) + { + for ( count = 0; count < iAddRemoveObservers->Count(); ++count ) + { + if ( ( *iAddRemoveObservers )[ count ]->iObserver == &aObserver && + ( *iAddRemoveObservers )[ count ]->iContentID && + !( *iAddRemoveObservers )[ count ]->iContentID->Compare( aContentID ) ) + { + return; + } + else if( addToServer && + !( *iAddRemoveObservers)[ count ]->iContentID->Compare( aContentID ) ) + { + addToServer = EFalse; + } + } + } + break; + case KEventModify: + if ( iModifyObservers ) + { + for ( count = 0; count < iModifyObservers->Count(); ++count ) + { + if ( ( *iModifyObservers )[ count ]->iObserver == &aObserver && + ( *iModifyObservers )[ count ]->iContentID && + !( *iModifyObservers )[ count ]->iContentID->Compare( aContentID ) ) + { + return; + } + else if( addToServer && + !( *iModifyObservers)[ count ]->iContentID->Compare( aContentID ) ) + { + addToServer = EFalse; + } + } + } + break; + default: + User::Leave(KErrArgument); + break; + } + + HBufC8* contentID = aContentID.AllocLC(); + struct TObserverData* observer = new (ELeave) TObserverData; + CleanupStack::PushL(observer); + + observer->iObserver = &aObserver; + observer->iContentID = contentID; + + switch( aEvent ) + { + case KEventAddRemove: + iAddRemoveObservers->AppendL( observer ); + break; + case KEventModify: + iModifyObservers->AppendL( observer ); + break; + default: + User::Leave(KErrArgument); + break; + } + + if ( !IsAdded() ) + { + CActiveScheduler::Add( this ); + } + + if ( !IsActive() ) + { + if( iStatus != KRequestPending ) + { + iStatus = KRequestPending; + iHandler->WaitForCompletion(iStatus); + } + SetActive(); + } + + // Register the type to the server + if ( addToServer ) + { + iHandler->RegisterForType(aEvent,contentID); + } + + CleanupStack::Pop(); // contentID + CleanupStack::Pop(); // observer; + } + +// ----------------------------------------------------------------------------- +// CDRMEventHandler::UnRegisterEventObserverL +// Removes the observer from the list of handlers. +// ----------------------------------------------------------------------------- +// +void CDRMEventHandler::UnRegisterEventObserverL( + MDRMEventObserver& aObserver, + const TDRMEventType& aEvent, + const TDesC8& aContentID ) + { + TInt count = 0; + TBool removeFromServer = ETrue; + + if( iIsDelayed ) + { + TDelayedObserverData* delayData = new (ELeave) TDelayedObserverData; + CleanupStack::PushL( delayData); + delayData->iRequest = KUnRegisterURIOperation; + delayData->iObserver = &aObserver; + delayData->iEventType = aEvent; + delayData->iContentID = aContentID.AllocLC(); + iDelayedObservers->AppendL( delayData ); + CleanupStack::Pop(); // iContentID; + CleanupStack::Pop(); // delayData; + return; + } + + // Check if something else uses the registration for this event type, if something + // Does set removeFromServer to EFalse so the registration is not removed from the + // server + switch ( aEvent ) + { + case KEventAddRemove: + if ( iAddRemoveObservers ) + { + for ( count = 0; count < iAddRemoveObservers->Count(); ++count ) + { + if( removeFromServer && + !( *iAddRemoveObservers )[ count ]->iContentID->Compare( aContentID ) && + ( *iAddRemoveObservers )[ count ]->iObserver != &aObserver ) + { + removeFromServer = EFalse; + } + } + } + break; + case KEventModify: + if ( iModifyObservers ) + { + for ( count = 0; count < iModifyObservers->Count(); ++count ) + { + if( removeFromServer && + !( *iModifyObservers )[ count ]->iContentID->Compare( aContentID ) && + ( *iModifyObservers )[ count ]->iObserver != &aObserver ) + { + removeFromServer = EFalse; + } + } + } + break; + default: + User::Leave(KErrArgument); + break; + } + + + // Remove the registrations from internal lists and possibly from the server + switch ( aEvent ) + { + case KEventAddRemove: + if ( iAddRemoveObservers ) + { + for ( count = 0; count < iAddRemoveObservers->Count(); ++count ) + { + if ( ( *iAddRemoveObservers )[ count ]->iObserver == &aObserver && + ( *iAddRemoveObservers )[ count ]->iContentID && + !( *iAddRemoveObservers )[ count ]->iContentID->Compare( aContentID ) ) + { + if ( removeFromServer ) + { + // Unregister the type from the server + iHandler->UnRegisterFromType(aEvent,(*iAddRemoveObservers)[ count ]->iContentID); + } + + // Free Memory + delete ( *iAddRemoveObservers )[ count ]->iContentID; + ( *iAddRemoveObservers )[ count ]->iContentID = NULL; + delete ( *iAddRemoveObservers )[ count ]; + ( *iAddRemoveObservers )[ count ] = NULL; + + // Delete the element from the table + iAddRemoveObservers->Delete( count ); + iAddRemoveObservers->Compress(); + return; + } + } + } + User::Leave(KErrNotFound); + break; + case KEventModify: + if ( iModifyObservers ) + { + for ( count = 0; count < iModifyObservers->Count(); ++count ) + { + if ( ( *iModifyObservers )[ count ]->iObserver == &aObserver && + ( *iModifyObservers )[ count ]->iContentID && + !( *iModifyObservers )[ count ]->iContentID->Compare( aContentID ) ) + { + + if( removeFromServer ) + { + // Unregister the type from the server + iHandler->UnRegisterFromType(aEvent,(*iModifyObservers)[ count ]->iContentID); + } + + // Free Memory + delete ( *iModifyObservers )[ count ]->iContentID; + ( *iModifyObservers )[ count ]->iContentID = NULL; + delete ( *iModifyObservers )[ count ]; + ( *iModifyObservers )[ count ] = NULL; + + // Delete the element from the table + iModifyObservers->Delete( count ); + iModifyObservers->Compress(); + return; + } + } + } + User::Leave(KErrNotFound); + break; + default: + User::Leave(KErrArgument); + break; + } + // Should never get here + User::Leave( KErrGeneral ); + } +// ----------------------------------------------------------------------------- +// CDRMEventHandler::SendEventL +// Sends the event to the client that sends it to the server +// Opens connection if it's not already open +// ----------------------------------------------------------------------------- +// +void CDRMEventHandler::SendEventL( MDRMEvent& aEvent, TRequestStatus& aStatus ) + { + RMemWriteStream output(iDataBuffer,DRMNotifier::KDRMSizeOfMessage); + CleanupClosePushL( output ); + + Mem::FillZ(iDataBuffer,DRMNotifier::KDRMSizeOfMessage); + + if(!iIsOpen) + { + if(!iHandler) + { + iHandler = new (ELeave) RDRMNotifierClient(iEventType,iEventTypeWait,iData,iWaitData); + } + User::LeaveIfError(iHandler->Connect()); + iIsOpen = ETrue; + } + + aEvent.ExternalizeL(output); + aEvent.GetEventType(*iEventType); + + iHandler->SendEvent(aStatus); + CleanupStack::PopAndDestroy(); + }; + +// ----------------------------------------------------------------------------- +// CDRMEventHandler::CDRMEventHandler +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CDRMEventHandler::CDRMEventHandler() : + CActive( EPriorityUserInput ), iIsOpen( EFalse ) +{ + // Nothing +} + +// ----------------------------------------------------------------------------- +// CDRMNotificationHandler::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CDRMEventHandler::ConstructL() +{ + iDataBuffer = static_cast(User::AllocL(DRMNotifier::KDRMSizeOfMessage)); + iEventType = static_cast(User::AllocL(sizeof(TDRMEventType*))); + iWaitDataBuffer = static_cast(User::AllocL(DRMNotifier::KDRMSizeOfMessage)); + iEventTypeWait = static_cast(User::AllocL(sizeof(TDRMEventType*))); + + iData = new( ELeave ) TPtr8(iDataBuffer,DRMNotifier::KDRMSizeOfMessage,DRMNotifier::KDRMSizeOfMessage); + iWaitData = new( ELeave) TPtr8(iWaitDataBuffer,DRMNotifier::KDRMSizeOfMessage,DRMNotifier::KDRMSizeOfMessage); + + iHandler = new (ELeave) RDRMNotifierClient(iEventType,iEventTypeWait,iData,iWaitData); + + User::LeaveIfError( iHandler->Connect() ); + iIsOpen = ETrue; + + iAddRemoveObservers = new( ELeave ) CArrayPtrSeg< TObserverData >( 4 ); + iModifyObservers = new( ELeave ) CArrayPtrSeg< TObserverData >( 4 ); + iTimeChangeObservers = new( ELeave ) CArrayPtrSeg< TObserverData >( 4 ); + iDelayedObservers = new( ELeave ) CArrayPtrSeg< TDelayedObserverData >( 4 ); + + Mem::FillZ(iDataBuffer,DRMNotifier::KDRMSizeOfMessage); + Mem::FillZ(iDataBuffer,DRMNotifier::KDRMSizeOfMessage); + Mem::FillZ(iEventType,sizeof(TDRMEventType)); + Mem::FillZ(iEventTypeWait,sizeof(TDRMEventType)); +} + +// ----------------------------------------------------------------------------- +// CDRMNotificationHandler::RunL +// Inherited from CActive +// ----------------------------------------------------------------------------- +// +void CDRMEventHandler::RunL() +{ + __ASSERT_DEBUG( iAddRemoveObservers, User::Invariant() ); + __ASSERT_DEBUG( iModifyObservers, User::Invariant() ); + + if ( iStatus == KErrCancel ) + { + return; + } + + TRAPD( error, HandleRunL() ); + + if( error && iIsDelayed ) + { + iIsDelayed = EFalse; + } + + // Discard all errors except this one. + if ( error == KErrServerTerminated ) + { + User::Leave( KErrServerTerminated ); + } + SetActive(); +} + +void CDRMEventHandler::DoCancel() +{ + iHandler->CancelRequest(); +} + +// ----------------------------------------------------------------------------- +// CDRMEventHandler::GetEventObjectLC +// ----------------------------------------------------------------------------- +// +MDRMEvent* CDRMEventHandler::GetEventObjectLC() + { + MDRMEvent* event = NULL; + switch(*iEventTypeWait) + { + case KEventAddRemove: + event = CDRMEventAddRemove::NewLC( ERightsObjectRecieved ); + break; + case KEventModify: + event = CDRMEventModify::NewLC(); + break; + case KEventTimeChange: + event = CDRMEventTimeChange::NewLC(); + break; + } + return event; + } + +// ----------------------------------------------------------------------------- +// CDRMEventHandler::HandleRunL +// ----------------------------------------------------------------------------- +// +void CDRMEventHandler::HandleRunL() +{ + MDRMEvent* object = NULL; + TDRMEventType event = 0; + TInt count = 0; + HBufC8* contentID = NULL; + TInt error = KErrNone; + + RMemReadStream input(iWaitDataBuffer,DRMNotifier::KDRMSizeOfMessage); + CleanupClosePushL( input ); + + if(!iIsOpen) + { + if(!iHandler) + { + iHandler = new (ELeave) RDRMNotifierClient(iEventType,iEventTypeWait,iData,iWaitData); + } + User::LeaveIfError(iHandler->Connect()); + iIsOpen = ETrue; + } + + object = GetEventObjectLC(); + if(!object) + { + User::Leave(KErrGeneral); + } + + object->InternalizeL(input); + + object->GetEventType(event); + + iIsDelayed = ETrue; + + switch ( event ) + { + case KEventAddRemove: + if ( iAddRemoveObservers ) + { + TRAPD( error_mem, contentID = (reinterpret_cast(object))->GetContentIDL()); + if ( error_mem ) + { + iIsDelayed = EFalse; + User::Leave( error_mem ); + } + CleanupStack::PushL(contentID); + + for ( count = 0; count < iAddRemoveObservers->Count(); ++count ) + { + if( !( *iAddRemoveObservers )[ count ]->iContentID || + !( *iAddRemoveObservers )[ count ]->iContentID->Compare( contentID->Des() ) ) + { + TRAP( error, ( *iAddRemoveObservers )[ count ]->iObserver->HandleEventL( object ) ); + } + } + CleanupStack::PopAndDestroy(); + } + break; + case KEventModify: + if ( iModifyObservers ) + { + TRAPD(error_mem, contentID = (reinterpret_cast(object))->GetContentIDL()); + if( error_mem ) + { + iIsDelayed = EFalse; + User::Leave( error_mem ); + } + CleanupStack::PushL(contentID); + + for ( count = 0; count < iModifyObservers->Count(); ++count ) + { + if( !( *iModifyObservers )[ count ]->iContentID || + !( *iModifyObservers )[ count ]->iContentID->Compare( contentID->Des() ) ) + { + TRAP( error, ( *iModifyObservers )[ count ]->iObserver->HandleEventL( object ) ); + } + } + CleanupStack::PopAndDestroy(); + } + break; + case KEventTimeChange: + if ( iTimeChangeObservers ) + { + for ( count = 0; count < iTimeChangeObservers->Count(); ++count ) + { + TRAP( error, ( *iTimeChangeObservers )[ count ]->iObserver->HandleEventL( object ) ); + } + } + break; + default: + iIsDelayed = EFalse; + User::Leave(KErrArgument); + break; + } + + // Ignore errors + if( error ) + { + // Do nothing + } + if( iStatus != KRequestPending ) + { + iStatus = KRequestPending; + iHandler->WaitForCompletion(iStatus); + } + CleanupStack::PopAndDestroy(); // object + CleanupStack::PopAndDestroy(); // input + iIsDelayed = EFalse; + + // Run delayed the adding and removing events in order + while ( iDelayedObservers->Count() ) + { + TInt ignore_error = KErrNone; + + switch( ( *iDelayedObservers )[ 0 ]->iRequest ) + { + case KRegisterOperation: + TRAP(ignore_error, + RegisterEventObserverL( *( *iDelayedObservers )[ 0 ]->iObserver, + ( *iDelayedObservers )[ 0 ]->iEventType ) ); + break; + case KRegisterURIOperation: + TRAP(ignore_error, + RegisterEventObserverL( *( *iDelayedObservers )[ 0 ]->iObserver, + ( *iDelayedObservers )[ 0 ]->iEventType, + ( *iDelayedObservers )[ 0 ]->iContentID->Des() ) ); + break; + case KUnRegisterOperation: + TRAP(ignore_error, + UnRegisterEventObserverL( *( *iDelayedObservers )[ 0 ]->iObserver, + ( *iDelayedObservers )[ 0 ]->iEventType ) ); + break; + case KUnRegisterURIOperation: + TRAP(ignore_error, + UnRegisterEventObserverL( *( *iDelayedObservers )[ 0 ]->iObserver, + ( *iDelayedObservers )[ 0 ]->iEventType, + ( *iDelayedObservers )[ 0 ]->iContentID->Des() ) ); + break; + default: + break; + } + if ( ( *iDelayedObservers )[ 0 ]->iContentID ) + { + delete ( *iDelayedObservers )[ 0 ]->iContentID; + ( *iDelayedObservers )[ 0 ]->iContentID = NULL; + } + delete ( *iDelayedObservers )[ 0 ]; + ( *iDelayedObservers )[ 0 ] = NULL; + iDelayedObservers->Delete( 0 ); + iDelayedObservers->Compress(); + } + } + +// End of File