--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mediator/src/Server/MediatorServerEventHandler.cpp Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,549 @@
+/*
+* 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: Event handling logic for the Mediator Server
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32base.h>
+
+#include "MediatorServerEventHandler.h"
+#include "MediatorServerObjects.h"
+#include "MediatorServiceDefs.h"
+#include "Debug.h"
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMediatorServerEventHandler::CMediatorServerEventHandler
+// -----------------------------------------------------------------------------
+//
+CMediatorServerEventHandler::CMediatorServerEventHandler(
+ CMediatorServerObjectHandler& aObjectHandler )
+ : CActive( EPriorityStandard ), iObjectHandler( aObjectHandler )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CMediatorServerEventHandler::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CMediatorServerEventHandler::ConstructL()
+ {
+ CActiveScheduler::Add( this );
+ }
+
+// -----------------------------------------------------------------------------
+// CMediatorServerEventHandler::NewL
+// -----------------------------------------------------------------------------
+//
+CMediatorServerEventHandler* CMediatorServerEventHandler::NewL(
+ CMediatorServerObjectHandler& aObjectHandler )
+ {
+ LOG(_L("[Mediator Server]\t CMediatorServerEventHandler::NewL"));
+ CMediatorServerEventHandler* self
+ = new( ELeave ) CMediatorServerEventHandler( aObjectHandler );
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CMediatorServerEventHandler::~CMediatorServerEventHandler
+// -----------------------------------------------------------------------------
+//
+CMediatorServerEventHandler::~CMediatorServerEventHandler()
+ {
+ Cancel();
+ // Clear event list
+ iEventServiceList.ResetAndDestroy();
+ }
+
+// -----------------------------------------------------------------------------
+// CMediatorServerEventHandler::DoCancel
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMediatorServerEventHandler::DoCancel()
+ {
+ TRACE(Print(_L("[Mediator Server]\t CMediatorServerEventHandler::DoCancel\n")));
+ }
+
+// -----------------------------------------------------------------------------
+// CMediatorServerEventHandler::RunL
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMediatorServerEventHandler::RunL()
+ {
+ TRACE(Print(_L("[Mediator Server]\t CMediatorServerEventHandler::RunL status %d\n"), iStatus.Int() ));
+
+ // Should be no errors unless cancel
+ if ( iStatus == KErrNone )
+ {
+ if ( iEventServiceList.Count() > 0 )
+ {
+ CEvent* serviceEvent = iEventServiceList[0]; // Take the first
+ iEventServiceList.Remove(0); // remove event from array
+ if ( serviceEvent )
+ {
+ // Get event information
+ TUid domain = serviceEvent->Domain();
+ TUid category = serviceEvent->Category();
+ TInt eventId = serviceEvent->Id();
+ const TDesC8& data = serviceEvent->ParameterData();
+
+ RPointerArray<MMediatorServerEventObserver>& observers
+ = serviceEvent->GetObservers();
+
+ // Loop through the observer array and send notifications
+ for ( TInt index = 0; index < observers.Count(); index++ )
+ {
+ MMediatorServerEventObserver* observer = observers[index];
+ if ( observer )
+ {
+ TRAP_IGNORE( observer->MediatorEventL( domain,
+ category,
+ eventId,
+ data ) );
+ }
+ }
+ delete serviceEvent;
+ }
+ // Continue if there's still more to serve
+ if ( iEventServiceList.Count() > 0 )
+ {
+ SetActive();
+ iStatus = KRequestPending;
+ TRequestStatus* stat = &iStatus;
+ User::RequestComplete( stat, KErrNone );
+ }
+ }
+ }
+ LOG(_L("[Mediator Server]\t CMediatorServerEventHandler::RunL end"));
+ }
+
+// -----------------------------------------------------------------------------
+// CMediatorServerEventHandler::RegisterEventListL
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMediatorServerEventHandler::RegisterEventListL(
+ TMediatorCategory aCategory,
+ const REventList& aEvents,
+ TSecureId aSecureId )
+ {
+ LOG(_L("[Mediator Server]\t CMediatorServerEventHandler::RegisterEventListL"));
+ // Check that domain exists --> if not add new
+ CDomain* domain = iObjectHandler.FindDomain( aCategory.iDomain );
+ if ( !domain )
+ {
+ domain = iObjectHandler.AddDomainL( aCategory.iDomain );
+ }
+
+ // Check that category exists --> if not add new
+ TInt ignore = 0; // not used here
+ CCategory* category = domain->FindCategory( aCategory.iCategory, ignore );
+ if ( !category )
+ {
+ category = domain->AddCategoryL( aCategory.iCategory );
+ }
+
+ // Loop through the events and add them to list
+ // Take the possible error to variable
+ TInt error = KErrNone;
+ TBool stop = EFalse;
+ TInt index = 0;
+ for ( index = 0; index < aEvents.Count() && !stop; index++ )
+ {
+ CEvent* newEvent = CEvent::NewL( aEvents[index] );
+ CleanupStack::PushL( newEvent );
+ newEvent->SetSecureId( aSecureId );
+ newEvent->SetCommitState( CItem::EAdded );
+ TInt addError = category->AddEvent( newEvent );
+ if ( addError )
+ {
+ ERROR_TRACE(Print(_L("[Mediator] CMediatorServerEventHandler::RegisterEventListL: addError=%d\n"), addError ) );
+ ERROR_TRACE(Print(_L("[Mediator] Failed to add event %d to category %d of domain %d\n"), newEvent->Id(),
+ aCategory.iCategory.iUid,
+ aCategory.iDomain.iUid ) );
+ // in case of error, delete event and take error
+ CleanupStack::PopAndDestroy( newEvent );
+ error = addError;
+ stop = ETrue;
+ }
+ else
+ {
+ // Event has been added properly --> just pop
+ CleanupStack::Pop( newEvent );
+ }
+ }
+
+ TRACE(Print(_L("[Mediator Server]\t Events registered:\n")));
+ TRACE(Print(_L("[Mediator Server]\t Success/count: %d/%d \tstatus: %d"), index, aEvents.Count(), error ));
+ // Check error if we need to do partial recovery
+ if ( error != KErrNone )
+ {
+ // Remove events that already have been added
+ category->RollbackEvents();
+ }
+ else
+ {
+ // Complete event list update
+ category->CommitEvents();
+
+ // Use the object handler to notify events
+ iObjectHandler.EventsAdded( aCategory.iDomain,
+ aCategory.iCategory,
+ aEvents );
+ }
+ // In the end leave if error --> client gets error code
+ User::LeaveIfError( error );
+ }
+
+// -----------------------------------------------------------------------------
+// CMediatorServerEventHandler::UnregisterEventListL
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMediatorServerEventHandler::UnregisterEventListL( TMediatorCategory aCategory,
+ const REventList& aEvents,
+ TSecureId aSecureId )
+ {
+ CCategory* category = iObjectHandler.CategoryL( aCategory );
+ TInt error = KErrNone;
+ if ( category )
+ {
+
+ TBool stop = EFalse;
+ TInt index = 0;
+ // Loop through the list of events and unregister those.
+ for ( index = 0; index < aEvents.Count() && !stop; index++ )
+ {
+ TInt eventIndex = 0;
+ TEvent removeEvent = aEvents[index];
+ CEvent* eventPtr = category->FindEvent( removeEvent.iEventId, eventIndex );
+ if ( !eventPtr )
+ {
+ ERROR_LOG(_L("[Mediator] CMediatorServerEventHandler::UnregisterEventListL: Event not found\n") );
+ ERROR_TRACE(Print(_L("[Mediator] Failed to remove event %d in category %d of domain %d\n"), removeEvent.iEventId,
+ aCategory.iCategory.iUid,
+ aCategory.iDomain.iUid ) );
+ error = KErrMediatorEventNotFound;
+ stop = ETrue;
+ }
+ else
+ {
+ // Found the event --> is it own registration
+ if ( eventPtr->SecureId() != aSecureId )
+ {
+ ERROR_LOG(_L("[Mediator] CMediatorServerEventHandler::UnregisterEventListL: Secure ID mismatch\n") );
+ ERROR_TRACE(Print(_L("[Mediator] eventPtr->SecureId()=0x%x, aSecureId=0x%x\n"), eventPtr->SecureId().iId,
+ aSecureId.iId ) );
+ error = KErrMediatorSecureIdMismatch;
+ stop = ETrue;
+ }
+ else // Should be ok to unregister
+ {
+ eventPtr->SetCommitState( CItem::ERemoved );
+ }
+ }
+ }
+
+ TRACE(Print(_L("[Mediator Server]\t Events unregistered:\n")));
+ TRACE(Print(_L("[Mediator Server]\t Success/count: %d/%d \tstatus: %d"), index, aEvents.Count(), error ));
+
+ // Check error status --> if there's error, need to roll back
+ if ( error != KErrNone )
+ {
+ // Cancel event removal
+ category->RollbackEvents();
+ }
+ else
+ {
+ // Complete event removal
+ category->CommitEvents();
+ // Use the object handler to notify event removal
+ iObjectHandler.EventsRemoved( aCategory.iDomain,
+ aCategory.iCategory,
+ aEvents );
+ }
+ }
+ // Leave in case of error situation
+ User::LeaveIfError( error );
+ }
+
+// -----------------------------------------------------------------------------
+// CMediatorServerEventHandler::SubscribeEventListL
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMediatorServerEventHandler::SubscribeEventListL(
+ TMediatorCategory aCategory,
+ const REventList& aEvents,
+ TCapabilitySet aCaps,
+ MMediatorServerEventObserver* aObserver )
+ {
+ LOG(_L("[Mediator Server]\t CMediatorServerEventHandler::SubscribeEventListL"));
+ TInt error = KErrNone;
+ TBool stop = EFalse;
+ TInt index = 0;
+ // Find domain & category
+ CCategory* category = iObjectHandler.CategoryL( aCategory );
+ if ( category )
+ {
+ // Loop through the list of subscribed events
+ for ( index = 0; index < aEvents.Count() && !stop; index++ )
+ {
+ TEvent newEvent = aEvents[index];
+ TInt ignore = 0; // Not used
+ CEvent* eventPtr = category->FindEvent( newEvent.iEventId, ignore );
+ if ( !eventPtr )
+ {
+ error = KErrMediatorEventNotFound;
+ stop = ETrue; // Partial failure --> stop processing
+ }
+ else
+ {
+ // Check capabilities
+ // Capabilities are checked so that boolean ETrue is returned
+ // when all parameter caps can be found from aCaps
+ if ( !aCaps.HasCapabilities( eventPtr->Policy() ) )
+ {
+#ifdef _DEBUG
+ for ( TInt index = 0; index < ECapability_Limit; index++ )
+ {
+ TCapabilitySet eventCaps = eventPtr->Policy();
+ TBool event = eventCaps.HasCapability( (TCapability) index );
+ TBool requestor = aCaps.HasCapability( (TCapability) index );
+ if ( event && !requestor )
+ {
+ ERROR_TRACE(Print(_L("[Mediator] CMediatorServerEventHandler::SubscribeEventListL: capability %d missing \n"), index ));
+ ERROR_TRACE(Print(_L("[Mediator] Failed to subscribe event %d in category %d of domain %d\n"), newEvent.iEventId,
+ aCategory.iCategory.iUid,
+ aCategory.iDomain.iUid ) );
+ }
+ }
+#endif // _DEBUG
+ error = KErrPermissionDenied;
+ stop = ETrue;
+ }
+ // Check (major) version match
+ if ( newEvent.iVersion.iMajor != eventPtr->Version().iMajor )
+ {
+ ERROR_LOG(_L("[Mediator] CMediatorServerEventHandler::SubscribeEventListL: Version mismatch\n"));
+ ERROR_TRACE(Print(_L("[Mediator] Registered=%d, subscribed=%d \n"), eventPtr->Version().iMajor,
+ newEvent.iVersion.iMajor ) );
+ ERROR_TRACE(Print(_L("[Mediator] Failed to subscribe event %d in category %d of domain %d\n"), newEvent.iEventId,
+ aCategory.iCategory.iUid,
+ aCategory.iDomain.iUid ) );
+ // There's a major version mismatch
+ error = KErrMediatorVersionMismatch;
+ stop = ETrue;
+ }
+ if ( !error ) // Everything ok?
+ {
+ // Everything is ok, register subscriber
+ TInt status = eventPtr->AddObserver( aObserver );
+ // If there's double subscription, ignore error
+ // otherwise return the error
+ if ( status && status != KErrMediatorAlreadySubscribed )
+ {
+ ERROR_TRACE(Print(_L("[Mediator] CMediatorServerEventHandler::SubscribeEventListL: error=%d\n"), status) );
+ ERROR_TRACE(Print(_L("[Mediator] Failed to subscribe event %d in category %d of domain %d\n"), newEvent.iEventId,
+ aCategory.iCategory.iUid,
+ aCategory.iDomain.iUid ) );
+ error = status;
+ stop = ETrue;
+ }
+ TRACE(Print(_L("[Mediator Server]\t subscription status: %d\n"), status));
+ }
+ }
+ }
+
+ TRACE(Print(_L("[Mediator Server]\t Events subscribed:\n")));
+ TRACE(Print(_L("[Mediator Server]\t Processed/Total: %d/%d \tstatus: %d"), index, aEvents.Count(), error ));
+ // Check error status --> if there's error, need to roll back
+ if ( error != KErrNone )
+ {
+ // Loop the subscribed events and unsubscribe those
+ // Index - 1 is because index points to failed item --> stop before processing it again
+ for ( TInt newIndex = 0; newIndex < index - 1; newIndex++ )
+ {
+ TEvent event = aEvents[newIndex];
+ TInt ignore = 0; // Not used
+ CEvent* eventPtr = category->FindEvent( event.iEventId, ignore );
+ if ( eventPtr )
+ {
+ // Nothing can be done in case of error --> ignore return value
+ TInt ignore = eventPtr->RemoveObserver( aObserver );
+ }
+ }
+ }
+ }
+ // In the end leave if we have error
+ User::LeaveIfError( error );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMediatorServerEventHandler::UnsubscribeEventListL
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMediatorServerEventHandler::UnsubscribeEventListL(
+ TMediatorCategory aCategory,
+ const REventList& aEvents,
+ MMediatorServerEventObserver* aObserver )
+ {
+ LOG(_L("[Mediator Server]\t CMediatorServerEventHandler::UnsubscribeEventListL"));
+ // Find correct category
+ CCategory* category = iObjectHandler.CategoryL( aCategory );
+ TInt error = KErrNone;
+ TInt index = 0;
+
+ if ( category )
+ {
+ TBool stop = EFalse;
+ // Loop through the list of events to be unsubscribed
+ for ( index = 0; index < aEvents.Count() && !stop; index++ )
+ {
+ TEvent event = aEvents[index];
+ TInt ignore = 0; // Not used
+ CEvent* eventPtr = category->FindEvent( event.iEventId, ignore );
+ if ( !eventPtr )
+ {
+ ERROR_LOG(_L("[Mediator] CMediatorServerEventHandler::UnsubscribeEventListL: event not found\n"));
+ ERROR_TRACE(Print(_L("[Mediator] Failed to unsubscribe event %d in category %d of domain %d\n"), event.iEventId,
+ aCategory.iCategory.iUid,
+ aCategory.iDomain.iUid ) );
+
+ error = KErrMediatorEventNotFound;
+ stop = ETrue; // Partial failure --> stop processing
+ }
+ else
+ {
+ // Everything is ok, unsubscribe
+ TInt status = eventPtr->RemoveObserver( aObserver );
+ // If there's no subscription existing, ignore error
+ // otherwise return the error
+ if ( status != KErrMediatorNoSubscription )
+ {
+ ERROR_TRACE(Print(_L("[Mediator] CMediatorServerEventHandler::UnsubscribeEventListL: status=%d\n"), status ) );
+ ERROR_TRACE(Print(_L("[Mediator] Failed to unsubscribe event %d in category %d of domain %d\n"), event.iEventId,
+ aCategory.iCategory.iUid,
+ aCategory.iDomain.iUid ) );
+ error = status;
+ stop = ETrue;
+ }
+ TRACE(Print(_L("[Mediator Server]\t unsubscribe status: %d\n"), status));
+ }
+ }
+
+ TRACE(Print(_L("[Mediator Server]\t Events unsubscribed:\n")));
+ TRACE(Print(_L("[Mediator Server]\t Success/count: %d/%d \tstatus: %d"), index, aEvents.Count(), error ));
+
+ // Check error status --> if there's error, need to roll back
+ if ( error != KErrNone )
+ {
+ // Loop the unsubscribed events and subscribe those
+ for ( TInt newIndex = 0; newIndex < index; newIndex++ )
+ {
+ TEvent event = aEvents[newIndex];
+ TInt ignore = 0; // Not used
+ CEvent* eventPtr = category->FindEvent( event.iEventId, ignore );
+ if ( eventPtr )
+ {
+ // Nothing can be done in case of error --> ignore return value
+ TInt ignore = eventPtr->AddObserver( aObserver );
+ }
+ }
+ }
+ }
+ // In the end leave if we have error
+ User::LeaveIfError( error );
+ }
+
+// -----------------------------------------------------------------------------
+// CMediatorServerEventHandler::RaiseEventL
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CMediatorServerEventHandler::RaiseEventL( TMediatorCategory aCategory,
+ MediatorService::TEvent aEvent,
+ const TDesC8& aData )
+ {
+ LOG(_L("[Mediator Server]\t CMediatorServerEventHandler::RaiseEventL"));
+ // Find correct category
+ CCategory* category = iObjectHandler.CategoryL( aCategory );
+ if ( category )
+ {
+ TInt ignore = 0; // Not used
+ CEvent* eventPtr = category->FindEvent( aEvent.iEventId, ignore );
+
+ // Check that event was found
+ if ( !eventPtr )
+ {
+ ERROR_LOG(_L("[Mediator] CMediatorServerEventHandler::RaiseEventL: event not found\n"));
+ ERROR_TRACE(Print(_L("[Mediator] Failed to raise event %d in category %d of domain %d\n"), aEvent.iEventId,
+ aCategory.iCategory.iUid,
+ aCategory.iDomain.iUid ) );
+ User::Leave( KErrMediatorEventNotFound );
+ }
+
+ // Check the version information match (major
+ if ( eventPtr->Version().iMajor != aEvent.iVersion.iMajor )
+ {
+ ERROR_LOG(_L("[Mediator] CMediatorServerEventHandler::RaiseEventL: Version mismatch\n"));
+ ERROR_TRACE(Print(_L("[Mediator] Registered=%d, subscribed=%d \n"), eventPtr->Version().iMajor,
+ aEvent.iVersion.iMajor ) );
+ ERROR_TRACE(Print(_L("[Mediator] Failed to raise event %d in category %d of domain %d\n"), aEvent.iEventId,
+ aCategory.iCategory.iUid,
+ aCategory.iDomain.iUid ) );
+ User::Leave( KErrMediatorVersionMismatch );
+ }
+
+
+ RPointerArray<MMediatorServerEventObserver>& observers
+ = eventPtr->GetObservers();
+
+ // Loop through the observer array and send notifications
+ for ( TInt index = 0; index < observers.Count(); index++ )
+ {
+ MMediatorServerEventObserver* observer = observers[index];
+ if ( observer )
+ {
+
+ TRAP_IGNORE( observer->MediatorEventL( aCategory.iDomain,
+ aCategory.iCategory,
+ aEvent.iEventId,
+ aData ) );
+ }
+ }
+ }
+ }
+
+// End of File