--- /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 <e32svr.h>
+
+#include <stfeventsystemerrorcodes.h>
+#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
+