diff -r bbd31066657e -r 8bb370ba6d1d testexecfw/stf/stffw/eventsystem/server/src/eventsystemsession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testexecfw/stf/stffw/eventsystem/server/src/eventsystemsession.cpp Fri Apr 09 10:46:28 2010 +0800 @@ -0,0 +1,631 @@ +/* +* Copyright (c) 2010 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: +* +*/ +#include + +#include +#include "eventsystemsession.h" +#include "eventsystemserver.h" + + +/** +Constructor +*/ +CEventSystemSession::CEventSystemSession() + { + //RDebug::Print(_L("STF [ESS]: CEventSystemSession::CEventSystemSession")); + } + +/** +Destructor +*/ +CEventSystemSession::~CEventSystemSession() + { + //RDebug::Print(_L("STF [ESS]: CEventSystemSession::~CEventSystemSession")); + // Check if there is waiting event registered + if(iWaitingEvent) + { + RDebug::Print(_L("STF [ESS]: CEventSystemSession::~CEventSystemSession iWaitingEvent is defined, will be handled")); + TInt i; + + for(i = 0; i < ((CEventSystemServer*)Server())->iWaitingEvents.Count(); i++) + { + CWaitingEvent* event = ((CEventSystemServer*)Server())->iWaitingEvents[i]; + // Check if this event matches + if(event == iWaitingEvent) + { + RDebug::Print(_L("STF [ESS]: CEventSystemSession::~CEventSystemSession iWaitingEvent found in the array")); + if(event->IsWaiting()) + { + // Complete event and remove it from list of waiting events + RDebug::Print(_L("STF [ESS]: CEventSystemSession::~CEventSystemSession iWaitingEvent in EEventWait state, cancelling")); + event->CancelEvent(); + ((CEventSystemServer*)Server())->iWaitingEvents.Remove(i); + RDebug::Print(_L("STF [ESS]: CEventSystemSession::~CEventSystemSession deleting iWaitingEvent")); + delete event; + event = NULL; + iWaitingEvent = NULL; + } + break; + } + } + } + + // Close session if not closed properly + if(iContainer) + { + CloseSession(); + } + } + + +/** +Called by client/server framework after +session has been successfully created. + +In effect, a second-phase constructor. + +Creates: + +1. the object index +2. the object container for this session. + +We are then ready for subsessions. +*/ +void CEventSystemSession::CreateL() + { +// RDebug::Print(_L("STF [ESS]: CEventSystemSession::CreateL")); +// // Create new object index +// iTestCaseRunnerObjectIndex = CObjectIx::NewL(); + + // Initialize the object container + // using the object container index in the server. + iContainer = ((CEventSystemServer*)Server())->NewContainerL(); + + // Adds session (updates counter) + ((CEventSystemServer*)Server())->AddSession(); + } + + +/** +Closes the session. + +It deletes the object index and object container. + +This could be done in the destructor, but it seems neater to do it here. +*/ +void CEventSystemSession::CloseSession() + { +// RDebug::Print(_L("STF [ESS]: CEventSystemSession::CloseSession")); + // Deletes the object index. +// delete iTestCaseRunnerObjectIndex; +// iTestCaseRunnerObjectIndex = NULL; + + // Deletes the object container + ((CEventSystemServer*)Server())->RemoveContainer(iContainer); + //delete iContainer; // RemoveContainer deletes the object + iContainer = NULL; + + // Removes session + ((CEventSystemServer*)Server())->RemoveSession(); + } + +/** +First line servicing of a client request. + +This function dispatches requests to the appropriate handler. +Some messages are handled by the session itself, and are +implemented as CCountSession member functions, while +other messages are handled by the subsession, and are +implemented as CCountSubSession member functions. +*/ +void CEventSystemSession::ServiceL(const RMessage2& aMessage) + { +// RDebug::Print(_L("STF [ESS]: CEventSystemSession::ServiceL")); + DispatchMessageL(aMessage); + } + + +/** +Called by ServiceL() + +It tests the function code and then delegates to +the appropriate function. +*/ +void CEventSystemSession::DispatchMessageL(const RMessage2& aMessage) + { +// RDebug::Print(_L("STF [ESS]: CEventSystemSession::DispatchMessageL function=[%d] message=[%x]"), aMessage.Function(), &aMessage); + TInt err; + + // First check for session-relative requests + switch(aMessage.Function()) + { + // Session relevant commands + case EEventSystemServCloseSession: + RDebug::Print(_L("STF [ESS]: CEventSystemSession::DispatchMessageL EEventSystemServCloseSession")); + CloseSession(); + RDebug::Print(_L("STF [ESS]: Completing message EEventSystemServCloseSession")); + aMessage.Complete(KErrNone); + break; + + case EEventSystemSetEvent: + RDebug::Print(_L("STF [ESS]: CEventSystemSession::DispatchMessageL EEventSystemSetEvent")); + TRAP(err, SetStateEventL(aMessage)); + RDebug::Print(_L("STF [ESS]: Completing message EEventSystemSetEvent with [%d]"), err); + aMessage.Complete(err); + break; + + case EEventSystemUnsetEvent: + RDebug::Print(_L("STF [ESS]: CEventSystemSession::DispatchMessageL EEventSystemUnsetEvent")); + TRAP(err, UnsetStateEventL(aMessage)); + RDebug::Print(_L("STF [ESS]: Completing message EEventSystemUnsetEvent with [%d]"), err); + aMessage.Complete(err); + break; + + case EEventSystemSetIndicationEvent: + RDebug::Print(_L("STF [ESS]: CEventSystemSession::DispatchMessageL EEventSystemSetIndicationEvent")); + TRAP(err, SetIndicationEventL(aMessage)); + RDebug::Print(_L("STF [ESS]: Completing message EEventSystemSetIndicationEvent with [%d]"), err); + aMessage.Complete(err); + break; + + case EEventSystemWaitEvent: + RDebug::Print(_L("STF [ESS]: CEventSystemSession::DispatchMessageL EEventSystemWaitEvent")); + TRAP(err, WaitForEventL(aMessage)); + if(err != KErrNone) + { + RDebug::Print(_L("STF [ESS]: Completing message EEventSystemWaitEvent with [%d]"), err); + aMessage.Complete(err); + } + break; + + case EEventSystemCancelWaitEvent: + RDebug::Print(_L("STF [ESS]: CEventSystemSession::DispatchMessageL EEventSystemCancelWaitEvent")); + TRAP(err, CancelWaitingEventL(aMessage)); + if(err != KErrNone) + { + RDebug::Print(_L("STF [ESS]: Completing message EEventSystemCancelWaitEvent with [%d]"), err); + aMessage.Complete(err); + } + break; + + case EEventSystemRequestEvent: + RDebug::Print(_L("STF [ESS]: CEventSystemSession::DispatchMessageL EEventSystemRequestEvent")); + TRAP(err, RequestEventL(aMessage)); + RDebug::Print(_L("STF [ESS]: Completing message EEventSystemRequestEvent with [%d]"), err); + aMessage.Complete(err); + break; + + case EEventSystemReleaseEvent: + RDebug::Print(_L("STF [ESS]: CEventSystemSession::DispatchMessageL EEventSystemReleaseEvent")); + TRAP(err, ReleaseEventL(aMessage)); + RDebug::Print(_L("STF [ESS]: Completing message EEventSystemReleaseEvent with [%d]"), err); + aMessage.Complete(err); + break; + + case EEventSystemRemoveInRequestedState: + RDebug::Print(_L("STF [ESS]: CEventSystemSession::DispatchMessageL EEventSystemRemoveInRequestedState")); + TRAP(err, RemoveInRequestedStateL(aMessage)); + RDebug::Print(_L("STF [ESS]: Completing message EEventSystemRemoveInRequestedState with [%d]"), err); + aMessage.Complete(err); + break; + + + default: + RDebug::Print(_L("STF [ESS]: CEventSystemSession::DispatchMessageL unknown function")); + PanicClient(aMessage, EEventSystemSessionUnknownMessage); + } + } + +/** +Panics the client +*/ +void CEventSystemSession::PanicClient(const RMessage2& aMessage, const TInt aPanic) const + { + RDebug::Print(_L("STF [ESS]: CEventSystemSession::PanicClient")); + _LIT(KMessage, "CEventSystemSession"); + aMessage.Panic(KMessage, aPanic); + } + + +/** +Set indication event +*/ +void CEventSystemSession::SetIndicationEventL(const RMessage2& aMessage) + { + // Get event data + RBuf eventName; + eventName.CreateL(KMaxEventName); + eventName.CleanupClosePushL(); + aMessage.ReadL(0, eventName); + + RDebug::Print(_L("STF [ESS]: setting indication event [%S]"), &eventName); + + // Notify requested events + NotifyRequestedEventsL(eventName); + + // Complete waiting events + CompleteWaitingEventsL(eventName); + + // Clean data + CleanupStack::PopAndDestroy(&eventName); + } + +/** +Request event +*/ +void CEventSystemSession::RequestEventL(const RMessage2& aMessage) + { + // Get event data + RBuf eventName; + eventName.CreateL(KMaxEventName); + eventName.CleanupClosePushL(); + aMessage.ReadL(0, eventName); + + TInt ownerId = aMessage.Int1(); + + // Check if event is not already requested + TInt i = 0; + if(((CEventSystemServer*)Server())->SearchForWaiting(eventName, ownerId, i)) + { + RDebug::Print(_L("STF [ESS]: Requested event [%S] already exists, leaving"), &eventName); + User::Leave(KErrAlreadyExists); + } + + // Create waiting event - it's first state will be EEventRequested + RDebug::Print(_L("STF [ESS]: Waiting event registered [%S]"), &eventName); + iWaitingEvent = CWaitingEvent::NewL(eventName, ownerId); + ((CEventSystemServer*)Server())->iWaitingEvents.Append(iWaitingEvent); + + // Clean data + CleanupStack::PopAndDestroy(&eventName); + } + +/** +Release event +*/ +void CEventSystemSession::ReleaseEventL(const RMessage2& aMessage) + { + // Get event data + RBuf eventName; + eventName.CreateL(KMaxEventName); + eventName.CleanupClosePushL(); + aMessage.ReadL(0, eventName); + + TInt ownerId = aMessage.Int1(); + + // Check if event is requested + TInt i = 0; + if(((CEventSystemServer*)Server())->SearchForWaiting(eventName, ownerId, i)) + { + CWaitingEvent* event = ((CEventSystemServer*)Server())->iWaitingEvents[i]; + + // If event is waiting, cancel it + if(event->IsWaiting()) + { + event->CancelEvent(); + } + + // Check if there is any candidate to be unset + TInt j = ((CEventSystemServer*)Server())->SearchForState(eventName); + if(j != KErrNotFound) + { + CStateEvent* state = ((CEventSystemServer*)Server())->iStateEvents[j]; + if(state->IsToBeUnset()) + { + ((CEventSystemServer*)Server())->iStateEvents.Remove(j); + delete state; + state = NULL; + } + } + + + // Delete waiting event + ((CEventSystemServer*)Server())->iWaitingEvents.Remove(i); + delete event; + event = NULL; + } + else // Event was not requested + { + RDebug::Print(_L("STF [ESS]: Event [%S] to be releases doesn't exist, leaving"), &eventName); + User::Leave(KErrNotFound); + } + + // Clean data + CleanupStack::PopAndDestroy(&eventName); + } + +/** +Wait for event +*/ +void CEventSystemSession::WaitForEventL(const RMessage2& aMessage) + { + __ASSERT_ALWAYS(iWaitingEvent == NULL, PanicClient(aMessage, EEventSystemSessionAlreadyWaiting)); + + // Get event data + RBuf eventName; + eventName.CreateL(KMaxEventName); + eventName.CleanupClosePushL(); + aMessage.ReadL(0, eventName); + + TInt ownerId = aMessage.Int1(); + + // Check if event is requested + TInt i = 0; + if(((CEventSystemServer*)Server())->SearchForWaiting(eventName, ownerId, i)) + { + CWaitingEvent* event = ((CEventSystemServer*)Server())->iWaitingEvents[i]; + + // Set in waiting state + iWaitingEvent = event; + event->WaitL(aMessage, this); + CompleteFromStateEventL(event); + } + else + { + RDebug::Print(_L("STF [ESS]: Event [%S] not requested"), &eventName); + User::Leave(EEventSystemNotRequested); + } + + // Clean data + CleanupStack::PopAndDestroy(&eventName); + } + +/** +Cancel waiting message from the same session +*/ +void CEventSystemSession::CancelWaitingEventL(const RMessage2& aMessage) + { + // Get event data + RBuf eventName; + eventName.CreateL(KMaxEventName); + eventName.CleanupClosePushL(); + aMessage.ReadL(0, eventName); + + TInt ownerId = aMessage.Int1(); + + // Search for waiting events + TInt i = 0; + while(((CEventSystemServer*)Server())->SearchForWaiting(eventName, ownerId, i)) + { + CWaitingEvent* event = ((CEventSystemServer*)Server())->iWaitingEvents[i]; + if(event->IsMatchingSession(this)) + { + // Complete event and remove it from list of waiting events + event->CancelEvent(); + ((CEventSystemServer*)Server())->iWaitingEvents.Remove(i); + // Delete waiting event + delete event; + event = NULL; + break; + } + //Increase index, so SearchForWaiting will start searching with following entries + i++; + } + aMessage.Complete(KErrNone); + + // Clean data + CleanupStack::PopAndDestroy(&eventName); + } + +/** +Check list of waiting events. If any of them is found, complete it. +*/ +void CEventSystemSession::CompleteWaitingEventsL(const TDesC& aEventName) + { + TInt i = 0; + while(((CEventSystemServer*)Server())->SearchForWaiting(aEventName, i)) + { + CWaitingEvent* event = ((CEventSystemServer*)Server())->iWaitingEvents[i]; + // Check if this event matches + if(event->IsWaiting()) + { + // Complete event + event->CompleteEventL(); + } + //Increase index, so SearchForWaiting will start searching with following entries + i++; + } + } + +/** +Check list of requested events. If any of them is found, notify about event. +*/ +void CEventSystemSession::NotifyRequestedEventsL(const TDesC& aEventName) + { + TInt i = 0; + while(((CEventSystemServer*)Server())->SearchForWaiting(aEventName, i)) + { + CWaitingEvent* event = ((CEventSystemServer*)Server())->iWaitingEvents[i]; + // Check if this event matches + if(event->IsRequested()) + { + // Complete event + event->NotifyRequestedEventL(); + } + //Increase index, so SearchForWaiting will start searching with following entries + i++; + } + } + +/** +Check list of state events. If any of them matches current waiting event, complete waiting event. +*/ +void CEventSystemSession::CompleteFromStateEventL(CWaitingEvent* aEvent) + { + TInt i = ((CEventSystemServer*)Server())->SearchForState(aEvent->EventName()); + if(i != KErrNotFound) + { + RDebug::Print(_L("STF [ESS]: CEventSystemSession::CompleteFromStateEventL event [%S]"), &aEvent->EventName()); + aEvent->CompleteEventL(); + } + } + +/** +Set state event +*/ +void CEventSystemSession::SetStateEventL(const RMessage2& aMessage) + { + // Get event data + RBuf eventName; + eventName.CreateL(KMaxEventName); + eventName.CleanupClosePushL(); + aMessage.ReadL(0, eventName); + + // Setting state event + RDebug::Print(_L("STF [ESS]: setting state event [%S]"), &eventName); + AddStateEventL(eventName); + + // Complete waiting events + CompleteWaitingEventsL(eventName); + + // Clean data + CleanupStack::PopAndDestroy(&eventName); + } + +/** +Unset state event +*/ +void CEventSystemSession::UnsetStateEventL(const RMessage2& aMessage) + { + // Get event data + RBuf eventName; + eventName.CreateL(KMaxEventName); + eventName.CleanupClosePushL(); + aMessage.ReadL(0, eventName); + + // Search for state event + TBool cannotBeUnset = EFalse; + CStateEvent* event = NULL; + + TInt i = ((CEventSystemServer*)Server())->SearchForState(eventName); + if(i != KErrNotFound) + { + // State event found, do further checking with requested events + event = ((CEventSystemServer*)Server())->iStateEvents[i]; + TInt j = 0; + while(((CEventSystemServer*)Server())->SearchForWaiting(eventName, j)) + { + CWaitingEvent* waiting = ((CEventSystemServer*)Server())->iWaitingEvents[j]; + // If waiting event is in requested state, we can't unset our event, we can only mark it to be unset later + if(waiting->IsRequested()) + { + // Set the flag + event->NotifyToBeUnset(ETrue); + cannotBeUnset = ETrue; + } + //Increase index, so SearchForWaiting will start searching with following entries + j++; + } + } + else + { + // State event was not found + RDebug::Print(_L("STF [ESS]: unset: state event [%S] not set, leaving with [%d]"), &eventName, KErrNotFound); + User::Leave(KErrNotFound); + } + + // Unsetting event because we have no found any requested events + if(!cannotBeUnset) + { + // Unsetting state event + RDebug::Print(_L("STF [ESS]: unsetting state event [%S]"), &eventName); + ((CEventSystemServer*)Server())->iStateEvents.Remove(i); + delete event; + event = NULL; + } + + // Clean data + CleanupStack::PopAndDestroy(&eventName); + } + +/** +Add state event in the state events array +*/ +void CEventSystemSession::AddStateEventL(const TDesC& aEventName) + { + CStateEvent *event; + + TInt i = ((CEventSystemServer*)Server())->SearchForState(aEventName); + if(i != KErrNotFound) + { + event = ((CEventSystemServer*)Server())->iStateEvents[i]; + // Event found, leave (or not, if event was unset but could not be due to some not released wait) + if(event->IsToBeUnset()) + { + // Reset the flag (equivalent to situation when theoretically unset event is set again) + event->NotifyToBeUnset(EFalse); + } + else + { + // Leave + RDebug::Print(_L("STF [ESS]: set: state event [%S] already set, leaving with [%d]"), &aEventName, KErrAlreadyExists); + User::Leave(KErrAlreadyExists); + } + } + else + { + // Event not found, add it + event = CStateEvent::NewL(aEventName); + ((CEventSystemServer*)Server())->iStateEvents.Append(event); + } + } + + +/** +Remove (like would be released) all requested events. +Waiting events will be handled via destructor of opened session +*/ +void CEventSystemSession::RemoveInRequestedStateL(const RMessage2& aMessage) + { + // Get event data + TInt ownerId = aMessage.Int0(); + RDebug::Print(_L("STF [ESS]: Removing all requested events of owner [%d], count=[%d]"), ownerId, ((CEventSystemServer*)Server())->iWaitingEvents.Count()); + + // Check if event is requested + TInt i = 0; + while(i < ((CEventSystemServer*)Server())->iWaitingEvents.Count()) + { + CWaitingEvent* event = ((CEventSystemServer*)Server())->iWaitingEvents[i]; + + if(event->OwnerId() == ownerId && event->IsRequested()) + { + // Check if there is any candidate to be unset + TInt j = ((CEventSystemServer*)Server())->SearchForState(event->EventName()); + if(j != KErrNotFound) + { + CStateEvent* state = ((CEventSystemServer*)Server())->iStateEvents[j]; + if(state->IsToBeUnset()) + { + ((CEventSystemServer*)Server())->iStateEvents.Remove(j); + delete state; + state = NULL; + } + } + + // And remove and delete + ((CEventSystemServer*)Server())->iWaitingEvents.Remove(i); + delete event; + event = NULL; + } + else + { + i++; + } + } + } +// EOF +