appfw/viewserver/server/VWSEVENT.CPP
changeset 0 2e3d3ce01487
child 10 469fa8a78de7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/appfw/viewserver/server/VWSEVENT.CPP	Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,1204 @@
+// Copyright (c) 1999-2009 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:
+//
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include "vwsinternal.h"
+#include "vwsdefpartner.h"
+#endif //SYMBIAN_ENABLE_SPLIT_HEADERS
+#include "VWSEVENT.H"
+#include "VWSERVER.H"
+#include "VWSDEBUG.H"
+#include "VWSPRIV.H"
+#include "vwspatchdata.h"
+
+#include <u32hal.h>
+
+
+
+//
+// class CVwsThreadWatcher
+//
+
+CVwsThreadWatcher::~CVwsThreadWatcher()
+	{
+	Cancel();
+	iThread.Close();
+	}
+
+CVwsThreadWatcher::CVwsThreadWatcher()
+	: CActive(EPriorityStandard)
+	{
+	}
+	
+TInt CVwsThreadWatcher::StartWatching(const TThreadId& aThreadId, const TCallBack& aCallBack)
+	{
+	iCallBack=aCallBack;
+	if(aThreadId!=iThread.Id())
+		{
+		if(IsAdded())
+			{
+			Deque();
+			iThread.Close();
+			}
+		TInt err=iThread.Open(aThreadId);
+		if (err==KErrNone)
+			{
+			CActiveScheduler::Add(this);
+			iThread.Logon(iStatus);
+			SetActive();
+			}
+		return err;
+		}
+	return KErrNone;
+	}
+
+void CVwsThreadWatcher::DoCancel()
+	{
+	iThread.LogonCancel(iStatus);
+	}
+
+void CVwsThreadWatcher::RunL()
+	{
+	iCallBack.CallBack();
+	}
+
+
+//
+// CVwsEventTimer.
+//
+
+CVwsEventTimer::~CVwsEventTimer()
+	{
+	delete iPeriodic;
+	}
+
+CVwsEventTimer* CVwsEventTimer::NewLC(const TTimeIntervalMicroSeconds32& aClientRequestTimeOut, const TTimeIntervalMicroSeconds32& aServerEventTimeOut)
+	{ // static
+	CVwsEventTimer* self = new(ELeave) CVwsEventTimer(aClientRequestTimeOut, aServerEventTimeOut);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+CVwsEventTimer::CVwsEventTimer(const TTimeIntervalMicroSeconds32& aClientRequestTimeOut, const TTimeIntervalMicroSeconds32& aServerEventTimeOut)
+	: iClientRequestTimeOut(aClientRequestTimeOut),
+	  iServerEventTimeOut(aServerEventTimeOut),
+	  iTimeOutState(EUndefined),
+	  iScreenDeviceChangeEvent(EFalse)
+	{}
+
+void CVwsEventTimer::ConstructL()
+	{
+	iPeriodic=CPeriodic::NewL(0);
+	}
+
+void CVwsEventTimer::Start(MVwsEventTimerObserver* aObserver,const TBool& aScreenDeviceChangeEvent)
+	{
+	iObserver=aObserver;
+
+	if (iPeriodic->IsActive())
+		{
+		iPeriodic->Cancel();
+		}
+	
+	TTimeIntervalMicroSeconds32 firstDelay(0);
+	iTimeOutState=EUndefined;
+
+	if (iClientRequestTimeOut < iServerEventTimeOut)
+		{
+		iTimeOutState=EClientRequestTimeOut;
+		firstDelay=iClientRequestTimeOut;
+		}
+	else 
+		{
+		iTimeOutState=EServerEventTimeOut;
+		firstDelay=iServerEventTimeOut;
+		}
+
+	TTimeIntervalMicroSeconds32 delay(firstDelay);
+	iPeriodic->Start(delay,delay,TCallBack(TimerCallBack,this));	
+	iScreenDeviceChangeEvent = aScreenDeviceChangeEvent;
+
+	}
+
+TInt CVwsEventTimer::TimerCallBack(TAny* aSelf)
+	{ // static
+	REINTERPRET_CAST(CVwsEventTimer*,aSelf)->DoTimerCallBack();
+	return 0;
+	}
+
+void CVwsEventTimer::DoTimerCallBack()
+	{
+	if (iPeriodic != NULL && iPeriodic->IsActive())
+		{
+		iPeriodic->Cancel();
+		}
+	if (iScreenDeviceChangeEvent && iObserver)
+		{
+		iObserver->HandleTimeOut(iTimeOutState);
+		}
+	else
+		{
+		if (iObserver)
+			{
+			iObserver->HandleTimeOut(iTimeOutState);
+			}
+		if (iTimeOutState == EClientRequestTimeOut || iTimeOutState == EIntermediateEventTimeOut) 
+			{
+			TTimeIntervalMicroSeconds32 delay;
+			if (iTimeOutState == EClientRequestTimeOut) 
+				{
+				//Normal delay is given before considering boosting the priority of an application
+				delay = iServerEventTimeOut.Int()-iClientRequestTimeOut.Int();
+				iTimeOutState = EIntermediateEventTimeOut;
+				}
+			else
+				{
+				//Delay of KTimeoutValueForPreemptedProcess is given after boosting priority of an application
+				TUint8 patchableConst = KTimeoutValueForPreemptedProcess;
+				#ifdef __WINS__
+				// For the emulator allow the constant to be patched via epoc.ini
+				UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty,
+					(TAny*)"KTimeoutValueForPreemptedProcess", &patchableConst); // read emulator property (if present)
+				#endif
+				delay = patchableConst;
+				iTimeOutState = EServerEventTimeOut;
+				}
+			
+            iPeriodic->Start(delay,delay,TCallBack(TimerCallBack,this));
+			}
+		}
+	}
+
+//
+// CVwsServerEvent.
+//
+
+CVwsServerEvent::CVwsServerEvent(CVwsServer& aServer,TType aType,CVwsEventQueue& aQueue)
+	:CVwsEvent(aType,aQueue),iServer(aServer)
+	{
+	}
+
+CVwsServerEvent::~CVwsServerEvent()
+	{
+	if (iObserved)
+		{
+		iObserved->NullifyObserver();
+		}
+	}
+
+
+void CVwsServerEvent::HandleLastOnQueue()
+	{
+	iServer.HandleLastServerEventOnQueue();
+	}
+
+
+//
+// CVwsServerEvent_Activate.
+//
+
+CVwsServerEvent_Activate::CVwsServerEvent_Activate(CVwsServer& aServer,TType aType,CVwsEventQueue& aQueue,const TVwsViewId& aViewIdToActivate,CVwsClientMessage* aClientMessage,const RMessage2& aMessage,const TThreadId& aClientThreadId,TVwsCompleteRequest aCompleteRequest,CVwsThreadWatcher* aThreadWatcher,CVwsEventTimer* aEventTimer,const RThread& aThreadOfClientInitiatingViewSwitch)
+	: CVwsServerEvent(aServer,aType,aQueue),
+	iViewIdToActivate(aViewIdToActivate),
+	iClientMessage(aClientMessage),
+	iNewViewClientThreadId(0),
+	iCompleteRequest(aCompleteRequest),
+	iClientThreadId(aClientThreadId),
+	iMessage(aMessage),
+	iThreadWatcher(aThreadWatcher),
+	iEventTimer(aEventTimer),
+	iThreadOfClientInitiatingViewSwitch(aThreadOfClientInitiatingViewSwitch)
+	{
+	}
+
+CVwsServerEvent_Activate::~CVwsServerEvent_Activate()
+	{
+	delete iClientMessage;
+	delete iThreadWatcher;
+	delete iEventTimer;
+	iThreadOfClientInitiatingViewSwitch.Close();
+	}
+
+void CVwsServerEvent_Activate::HandleTimeOut(CVwsEventTimer::TTimeOut aTimeOut)
+	{
+	if (aTimeOut==CVwsEventTimer::EServerEventTimeOut && iServer.IsServerEventTimeOutEnabled())
+		{
+		if (iState==EActivationRequested)
+			{
+			LOG3(CVwsLog::ENormal,_L("PANIC CLIENT \"%x\" for timing out activation view event - activation request was not completed"),iViewIdToActivate.iAppUid.iUid);
+			if (TUint(iNewViewClientThreadId)!=0)
+				{
+				CVwsSession* newViewSession=iServer.SessionByThreadId(iNewViewClientThreadId);
+				if (newViewSession)
+					{
+					if (iServer.IsPriorityBoostBeforePanicEnabled())
+						{
+						if (iServer.InitializationFinished())
+							{
+							newViewSession->PanicClient(EVwsViewActivationEventTimeOut);
+							}
+						}
+					else
+						{
+						newViewSession->PanicClient(EVwsViewActivationEventTimeOut);
+						}
+					}
+				}
+			}
+		else if (iState==EDeactivationRequested)
+			{
+			LOG3(CVwsLog::ENormal,_L("PANIC CLIENT \"%x\" for timing out activation view event - deactivation request was not completed"),iServer.ActiveView().iAppUid.iUid);
+			CVwsSession* sessionWithActiveView=iServer.ActiveViewSession();
+			if (sessionWithActiveView)
+				{
+				if (iServer.IsPriorityBoostBeforePanicEnabled())
+					{
+					if (iServer.InitializationFinished())
+						{
+						sessionWithActiveView->PanicClient(EVwsViewDeactivationEventTimeOut);
+						}
+					}
+				else
+					{
+					sessionWithActiveView->PanicClient(EVwsViewDeactivationEventTimeOut);
+					}
+				}
+			}
+		else
+			{
+			LOG4(CVwsLog::EQuiet,_L("Aborting activation of view \"%x,%x\" - server event processing timed-out"),iViewIdToActivate.iAppUid.iUid,iViewIdToActivate.iViewUid.iUid);
+			Complete(KErrCancel);
+			}
+		}
+	else if (aTimeOut==CVwsEventTimer::EClientRequestTimeOut)
+			{
+			LOG2(CVwsLog::ELoud,_L("Activation event timer has passed client request time-out"));
+			if (iCompleteRequest==ECompleteRequest && iServer.SessionByThreadId(iClientThreadId)!=NULL)
+				{
+				LOG2(CVwsLog::ELoud,_L("Client request timed-out - silently completing request"));
+				iCompleteRequest=EDoNotCompleteRequest;
+				iMessage.Complete(KErrNone);
+				}
+			}
+		else if (aTimeOut==CVwsEventTimer::EIntermediateEventTimeOut) 
+           { 
+           if (iState==EActivationRequested) 
+               { 
+               iServer.BoostPriority(iServer.SessionByThreadId(iNewViewClientThreadId)); 
+               } 
+           else if (iState==EDeactivationRequested) 
+               { 
+               iServer.BoostPriority(iServer.ActiveViewSession()); 
+               } 
+           } 
+
+	}
+
+void CVwsServerEvent_Activate::ProcessEventL()
+	{
+LOG4(CVwsLog::ELoud,_L("Starting to process activation of \"%x,%x\""),iViewIdToActivate.iAppUid.iUid,iViewIdToActivate.iViewUid.iUid);
+
+	RequestActivateNewView();
+	}
+
+#ifdef _DEBUG
+void CVwsServerEvent_Activate::RequestCompleted(TRequestType aType,TInt aError,const RMessage2&)
+#else
+void CVwsServerEvent_Activate::RequestCompleted(TRequestType /*aType*/,TInt aError,const RMessage2&)
+#endif // _DEBUG
+	{
+	switch (iState)
+		{
+		case EPending:
+			ASSERT(EFalse);
+			break;
+		case EActivationRequested:
+			ASSERT(aType==MVwsSessionObserver::EActivation);
+			LOG5(CVwsLog::ELoud,_L("Session request complete [activation event state: EActivationRequested; view to activate: \"%x,%x\", error: %d]"),iViewIdToActivate.iAppUid.iUid,iViewIdToActivate.iViewUid.iUid,aError);
+			if (aError)
+				{
+				if (aError==KErrViewWrongMode)
+					{
+					RequestActivateSystemDefaultView();
+					}
+				else
+					{
+					Complete(aError);
+					}
+				}
+			else
+				{
+				TVwsViewId viewToDeactivate(iServer.ActiveView());
+				// When an application whose view has to be activated is in background, the currently active view will not be deactivated.
+				// Note: Switching between different views of the same application must be followed by deactivation of old view
+				if ((iMessage.Int3() && !(iServer.IsAppInForeground())) && (viewToDeactivate.iAppUid != iViewIdToActivate.iAppUid))
+					{
+					LOG4(CVwsLog::ELoud,_L("\"%x,%x\", is activated at the background, so foreground view will not be deactivated"),iViewIdToActivate.iAppUid.iUid,iViewIdToActivate.iViewUid.iUid);
+					Complete(KErrNone);
+					}
+				else
+					{
+				RequestDeactivateOldView();
+					}
+				}
+			break;
+		case ESystemDefaultActivationRequested:
+			ASSERT(aType==MVwsSessionObserver::EActivation);
+			if (aError)
+				{
+				LOG3(CVwsLog::EQuiet,_L("Failed to activate system default view, error: %d"),aError);
+				RequestActivateSystemDefaultView();
+				}
+			else
+				{
+				RequestDeactivateOldView();
+				}
+			break;
+		case EDeactivationRequested:
+			ASSERT(aType==MVwsSessionObserver::EDeactivation);
+			LOG5(CVwsLog::ELoud,_L("Session request complete [activation event state: EDeactivationRequested; view to activate: \"%x,%x\", error: %d]"),iViewIdToActivate.iAppUid.iUid,iViewIdToActivate.iViewUid.iUid,aError);
+			iServer.HandleDeactivation(iServer.ActiveView(),iViewIdToActivate);
+			Complete(KErrNone);
+			break;
+		default:
+		case EAppStartRequested:
+			ASSERT(EFalse);
+		}
+
+// Disable unused parameter warning under release builds
+#pragma warning (disable: 4100) 
+	}
+#pragma warning (default: 4100)
+
+void CVwsServerEvent_Activate::NowObserving(CVwsSessionEvent* aObserved)
+	{
+	if(iObserved)
+	    {
+	    iObserved->NullifyObserver();
+	    }
+       	iObserved = aObserved;
+	}
+
+void CVwsServerEvent_Activate::NullifyObserved()
+	{
+	iObserved = NULL;	
+	}
+
+void CVwsServerEvent_Activate::HandleViewAdded(const TVwsViewId& aViewId, const TThreadId& aNewViewClientThreadId)
+	{
+	ASSERT(iState==EAppStartRequested);
+	if (aViewId.iAppUid==iViewIdToActivate.iAppUid
+	  &&aViewId.iAppUid==aViewId.iViewUid)
+		{
+		iViewIdToActivate = aViewId;
+		}
+	if (aViewId==iViewIdToActivate)
+		{
+		iServer.SetViewAdditionObserver(NULL);
+		
+		// set iNewViewClientThreadId to indicate that the new view should come from the session specified if possible
+		iNewViewClientThreadId = aNewViewClientThreadId;
+		RequestActivateNewView();
+		}
+	}
+
+void CVwsServerEvent_Activate::RequestActivateNewView()
+	{
+	CVwsSession* sessionWithNewView=iServer.SessionByThreadIdAndAppUid(iClientThreadId,iViewIdToActivate.iAppUid);
+	
+	// iNewViewClientThreadId may have been set by the caller to indicate a preference between
+	// sessions with the same App Uid
+	if (sessionWithNewView==NULL && iNewViewClientThreadId!=TThreadId(0))
+		{
+		sessionWithNewView=iServer.SessionByThreadIdAndAppUid(iNewViewClientThreadId,iViewIdToActivate.iAppUid);
+		}
+
+	if (sessionWithNewView==NULL)
+		{
+		sessionWithNewView=iServer.SessionByUid(iViewIdToActivate.iAppUid);
+		}
+
+	if (sessionWithNewView==NULL || (sessionWithNewView && sessionWithNewView->IsExiting()))
+		{
+		RequestAppStart();
+		}
+	else
+		{
+		iNewViewClientThreadId=sessionWithNewView->ClientThreadId();
+		DoRequestActivateNewView(*sessionWithNewView);
+		}
+	}
+
+void CVwsServerEvent_Activate::RequestActivateSystemDefaultView()
+	{
+	iServer.GetSystemDefaultView(iViewIdToActivate);
+	CVwsSession* sessionWithSystemDefaultView=iServer.SessionByUid(iViewIdToActivate.iAppUid);
+	// need an empty client message 
+	CVwsClientMessage* emptyClientMessage=CVwsClientMessage::New();
+	if (emptyClientMessage==NULL)
+		{
+		Complete(KErrNoMemory);
+		}
+
+	if (sessionWithSystemDefaultView)
+		{
+		iNewViewClientThreadId=sessionWithSystemDefaultView->ClientThreadId();
+		RequestClientActivation(*sessionWithSystemDefaultView,emptyClientMessage,ESystemDefaultActivationRequested);
+		}
+	else if (iThreadWatcher==NULL)
+		{
+		// app died
+		StopActivationProfile();
+		ASSERT(iState!=EAppStartRequested);	// Already asked to start app once.
+		StartAppStartProfile();
+		iServer.SetViewAdditionObserver(this);
+		TThreadId appThreadId;
+		iClientMessage = emptyClientMessage;
+		TInt err=iServer.StartApp(iViewIdToActivate.iAppUid,appThreadId);
+		if (err)
+			{
+			LOG3(CVwsLog::EQuiet,_L("App start FAILED with %d"),err);
+			Complete(err);
+			}
+		else
+			{
+			iState=EAppStartRequested;
+			}
+		}
+	else
+		{
+		delete emptyClientMessage;
+		}
+	}
+
+void CVwsServerEvent_Activate::RequestAppStart()
+	{
+	ASSERT(iState!=EAppStartRequested);	// Already asked to start app once.
+	StartAppStartProfile();
+	iServer.SetViewAdditionObserver(this);
+	TThreadId appThreadId;
+	TInt err=iServer.StartApp(iViewIdToActivate.iAppUid,appThreadId);
+	if (err)
+		{
+		LOG3(CVwsLog::EQuiet,_L("App start FAILED with %d"),err);
+		Complete(err);
+		}
+	else
+		{
+		iState=EAppStartRequested;
+		err=iThreadWatcher->StartWatching(appThreadId,TCallBack(&AppThreadWatcherCallBack,this));
+		if (err)
+			{
+			LOG3(CVwsLog::EQuiet,_L("App start FAILED with %d"),err);
+			Complete(err);
+			}
+		}
+	}
+
+TInt CVwsServerEvent_Activate::AppThreadWatcherCallBack(TAny* aPtr)
+	// static
+	{
+	LOG2(CVwsLog::EQuiet,_L("App start FAILED with app client thread death"));
+	REINTERPRET_CAST(CVwsServerEvent_Activate*,aPtr)->Complete(KErrCancel);
+	return 0;
+	}
+
+TInt CVwsServerEvent_Activate::RequestClientActivation(CVwsSession& aSession,CVwsClientMessage* aClientMessage,TState aNewState)
+	{
+	TRAPD(error,
+			aSession.RequestClientActivationL(*this,iViewIdToActivate,iServer.ActiveView(),aClientMessage,iThreadOfClientInitiatingViewSwitch));
+	if (error)
+		{
+		LOG3(CVwsLog::ELoud,_L("RequestClientActivationL FAILED with %d - unable to activate new view"),error);
+		if(aSession.IsLeaveAfterOwnershipTaken())
+			{
+			aSession.ResetLeaveAfterOwnershipTaken();
+			iClientMessage=NULL;
+			}
+		Complete(error);
+		}
+	else
+		{
+		iClientMessage=NULL; // The session is now the owner of the custom message buf.
+		iState=aNewState;
+		}
+	return error;
+	}
+
+void CVwsServerEvent_Activate::CustomCrossCheck(CVwsSession& aSessionWithNewView)
+	{
+	if (iClientMessage->iMessageId == KUidCustomCrossCheck && iClientMessage->iMessage == NULL)
+		{
+		iClientMessage->iMessageId = KNullUid;
+		TVwsViewId viewId;
+		if (aSessionWithNewView.GetTopView(viewId) == KErrNone)
+			{
+#ifdef _DEBUG
+			if (iViewIdToActivate != viewId)
+				{
+				LOG4(CVwsLog::ELoud,_L("Cross check to \"%x,%x\""), viewId.iAppUid.iUid, viewId.iViewUid.iUid);
+				}
+#endif //_DEBUG
+			iViewIdToActivate = viewId;
+			iClientMessage->iMessageId = KNullUid;
+			}
+		}
+	}
+
+void CVwsServerEvent_Activate::DoRequestActivateNewView(CVwsSession& aSessionWithNewView)
+	{
+	StopAppStartProfile();
+	delete iThreadWatcher;
+	iThreadWatcher=NULL;
+
+	iEventTimer->Start(this,EFalse);
+
+	if (iClientMessage)
+		{
+		CustomCrossCheck(aSessionWithNewView);
+		}
+
+	if (iServer.CheckViewExists(aSessionWithNewView.ClientThreadId(),iViewIdToActivate)==KErrNotFound)
+		{
+		LOG4(CVwsLog::EQuiet,_L("Aborting activation - view \"%x,%x\" not found"),iViewIdToActivate.iAppUid.iUid,iViewIdToActivate.iViewUid.iUid);
+		Complete(KErrNotFound);
+		return;
+		}
+
+	StartActivationProfile();
+	RequestClientActivation(aSessionWithNewView,iClientMessage,EActivationRequested);
+	}
+
+void CVwsServerEvent_Activate::RequestDeactivateOldView()
+	{
+	StopActivationProfile();
+	TVwsViewId viewToDeactivate(iServer.ActiveView());
+	CVwsSession* sessionWithOldView=iServer.ActiveViewSession();
+	CVwsSession* sessionWithNewView=iServer.SessionByThreadIdAndAppUid(iClientThreadId,iViewIdToActivate.iAppUid);
+		
+	//If the client that is requesting view activation is same as the client which has the new active view, ie, reactivation of same view, 
+	//then the session with new active view is taken. 
+	if (sessionWithNewView==NULL && iNewViewClientThreadId!=TThreadId(0))
+		{
+		sessionWithNewView=iServer.SessionByThreadIdAndAppUid(iNewViewClientThreadId,iViewIdToActivate.iAppUid);
+		}
+	
+	if (sessionWithNewView==NULL)
+		{
+		sessionWithNewView=iServer.SessionByUid(iViewIdToActivate.iAppUid);
+		}
+	
+	if (viewToDeactivate.iAppUid.iUid && (viewToDeactivate != iViewIdToActivate || sessionWithOldView != sessionWithNewView))
+		{
+		if (sessionWithOldView==NULL)
+			{	// Session with old view has disconnected, so abort deactivation.
+			LOG4(CVwsLog::ELoud,_L("Aborting deactivation of view \"%x,%x\" - client disconnected"),viewToDeactivate.iAppUid.iUid,viewToDeactivate.iViewUid.iUid);
+			Complete(KErrNone);
+			}
+		else
+			{
+			TBool differentInstanceOfSameApp = EFalse;
+			if (viewToDeactivate.iAppUid == iViewIdToActivate.iAppUid && sessionWithOldView != sessionWithNewView)
+				differentInstanceOfSameApp = ETrue;
+			TRAPD(err,sessionWithOldView->RequestClientDeactivationL(*this,viewToDeactivate,iViewIdToActivate, differentInstanceOfSameApp));
+			if (err)
+				{
+				LOG3(CVwsLog::ELoud,_L("RequestClientDeactivationL FAILED with %d - unable to deactivate currently active view"),err);
+				Complete(err);
+				}
+			else
+				{
+				iState=EDeactivationRequested;
+				}
+			}
+		}
+	else
+		{
+		// No view to deactivate, so complete.
+		LOG2(CVwsLog::ELoud,_L("Aborting deactivation - no view to deactivate"));
+		Complete(KErrNone);
+		}
+	}
+
+void CVwsServerEvent_Activate::Complete(TInt aError)
+	{
+	LOG5(CVwsLog::ELoud,_L("Completing activation of \"%x,%x\" with %d"),iViewIdToActivate.iAppUid,iViewIdToActivate.iViewUid,aError);
+	if (aError==KErrNone && TUint(iNewViewClientThreadId)!=0) 
+		{
+		iServer.HandleActivation(iViewIdToActivate,iServer.ActiveView());
+		TVwsViewId viewToDeactivate(iServer.ActiveView());
+		// The active active viewid will be set in the server when
+		// 1. Application whose view is getting activated is in foreground
+		// 2. Switching between different views of the same application
+		if(iServer.IsAppInForeground() || (iViewIdToActivate.iAppUid == viewToDeactivate.iAppUid))
+			{
+			iServer.SetActiveView(iNewViewClientThreadId,iViewIdToActivate);	
+			}
+		}
+	iServer.SetViewAdditionObserver(NULL);
+	if ((iCompleteRequest==ECompleteRequest) && (iServer.SessionByThreadId(iClientThreadId)!=NULL))
+		{
+		if(!iMessage.IsNull())
+			{
+			iMessage.Complete(aError);
+			}
+		}
+#ifdef __DO_LOGGING__
+	else if (iCompleteRequest==ECompleteRequest)
+		{
+		LOG2(CVwsLog::ELoud,_L("Client requesting activation not current - completing activation will not complete message handle"));
+		}
+#endif
+	ReportEventProcessed();
+	}
+
+void CVwsServerEvent_Activate::HandleSessionRemoval(const TThreadId& aClientThreadId)
+	{
+	TThreadId threadId(aClientThreadId);
+	TBool iCancel=EFalse;
+	if (iState==EDeactivationRequested)
+		{
+		CVwsSession* sessionWithActiveView=iServer.ActiveViewSession();
+		if (sessionWithActiveView && threadId==sessionWithActiveView->ClientThreadId())
+			{
+			LOG2(CVwsLog::ELoud,_L("Client with active view removed while session deactivation request outstanding"));
+			iCancel=ETrue;
+			}
+#ifdef __DO_LOGGING__
+		else if (threadId==iNewViewClientThreadId)
+			{
+			LOG2(CVwsLog::ELoud,_L("Client with new view removed while session deactivation request outstanding - waiting for deactivation to complete"));
+			}
+#endif
+		}
+	else if (threadId==iNewViewClientThreadId)
+		{
+		LOG2(CVwsLog::ELoud,_L("Client with new view removed"));
+		iCancel=ETrue;
+		}
+	if (iCancel)
+		{
+		LOG2(CVwsLog::ELoud,_L("Client removal means activation event will not complete normally - activation cancelled"));
+		Complete(KErrCancel);
+		}
+	}
+
+void CVwsServerEvent_Activate::StartAppStartProfile()
+	{
+	ASSERT(iWhichProfile==ENone);
+	iWhichProfile=EAppStart;
+	}
+
+void CVwsServerEvent_Activate::StopAppStartProfile()
+	{
+	if (iWhichProfile==EAppStart)
+		{
+		iWhichProfile=ENone;
+		}
+	}
+
+void CVwsServerEvent_Activate::StartActivationProfile()
+	{
+	ASSERT(iWhichProfile==ENone);
+	iWhichProfile=EActivation;
+	}
+
+void CVwsServerEvent_Activate::StopActivationProfile()
+	{
+	if (iWhichProfile==EActivation)
+		{
+		iWhichProfile=ENone;
+		}
+	}
+
+
+//
+// CVwsServerEvent_ScreenDeviceChanged.
+//
+
+CVwsServerEvent_ScreenDeviceChanged::CVwsServerEvent_ScreenDeviceChanged(CVwsServer& aServer,CVwsEventQueue& aQueue,CVwsThreadWatcher* aThreadWatcher,CVwsEventTimer* aEventTimer)
+	: CVwsServerEvent_Activate(aServer,CVwsServerEvent::ERejectPairs,aQueue,KNullViewId,NULL,RMessage2(),0,EDoNotCompleteRequest,aThreadWatcher,aEventTimer,RThread()),
+	iThreadWatcher(aThreadWatcher) ,iEventTimer(aEventTimer)
+	{
+	}
+
+CVwsServerEvent_ScreenDeviceChanged::~CVwsServerEvent_ScreenDeviceChanged()
+	{
+	}
+
+void CVwsServerEvent_ScreenDeviceChanged::ProcessEventL()
+	{
+	LOG2(CVwsLog::ELoud,_L("Started processing of screen device changed event"));
+	if(iServer.ActiveViewSession()!=NULL)
+		{
+		TThreadId activeClientThread = iServer.ActiveViewSession()->ClientThreadId();
+		TRAPD(err,iThreadWatcher->StartWatching(activeClientThread,TCallBack(&AppThreadWatcherCallBack,this)));
+		iEventTimer->Start(this,ETrue);
+		if (err)
+			{
+			Complete(err);
+			}
+		}
+	TVwsViewId activeView(iServer.ActiveView());
+	if (activeView.iAppUid.iUid)
+		{
+		RequestChangeNotification();
+		}
+	else
+		{
+		LOG2(CVwsLog::ELoud,_L("No active view, so ignoring screen device changed event"));
+		Complete(KErrNone);
+		}
+	}
+TInt CVwsServerEvent_ScreenDeviceChanged::AppThreadWatcherCallBack(TAny* aPtr)
+	// static
+	{
+	LOG2(CVwsLog::ELoud,_L("Client thread died while processing Screendevice change event"));
+	REINTERPRET_CAST(CVwsServerEvent_ScreenDeviceChanged*,aPtr)->Complete(KErrCancel);
+	return 0;
+	}
+
+void CVwsServerEvent_ScreenDeviceChanged::RequestCompleted(TRequestType aType,TInt aError,const RMessage2& aMessage)
+	{
+	switch (iScreenDeviceNotificationState)
+		{
+		case EPending:
+			ASSERT(EFalse);
+			break;
+		case EScreenDeviceChangeNotificationRequested:
+			{
+			ASSERT(aType==EScreenDeviceChangeNotification);
+			TRAPD(err,RequestActivationAsRequiredL(aMessage));
+			if (err)
+				{
+				LOG3(CVwsLog::ELoud,_L("CVwsClientMessage::NewL FAILED with %d, unable to activate view in responce to screen device changed event"),err);
+				RequestActivateSystemDefaultView();
+				}
+			}
+			break;
+		case EViewActivationRequested:
+		case EDefaultSystemViewActivationRequested:
+			CVwsServerEvent_Activate::RequestCompleted(aType,aError,aMessage);
+			break;
+		default:
+			ASSERT(EFalse);
+		}
+
+// Disable unused parameter warning under release builds
+#pragma warning (disable: 4100) 
+	}
+#pragma warning (default: 4100)
+
+void CVwsServerEvent_ScreenDeviceChanged::NowObserving(CVwsSessionEvent* aObserved)
+	{
+	if(iObserved)
+	    {
+	    iObserved->NullifyObserver();
+	    }
+	iObserved = aObserved;
+	}
+
+void CVwsServerEvent_ScreenDeviceChanged::NullifyObserved()
+	{
+	iObserved = NULL;	
+	}
+
+void CVwsServerEvent_ScreenDeviceChanged::RequestChangeNotification()
+	{
+	const TVwsViewId activeView(iServer.ActiveView());
+	CVwsSession* sessionWithActiveView=iServer.ActiveViewSession();
+	ASSERT(sessionWithActiveView); // Session with active view MUST be found.
+	TRAPD(err,sessionWithActiveView->RequestScreenDeviceChangeNotificationL(*this,activeView));
+	if (err)
+		{
+		LOG3(CVwsLog::ELoud,_L("RequestScreenDeviceChangeNotificationL FAILED with %d, unable to notify screen device changed"),err);
+		iScreenDeviceNotificationState=EDefaultSystemViewActivationRequested;
+		RequestActivateSystemDefaultView();
+		}
+	else
+		{
+		iScreenDeviceNotificationState=EScreenDeviceChangeNotificationRequested;
+		}
+	}
+
+void CVwsServerEvent_ScreenDeviceChanged::RequestActivationAsRequiredL(const RMessage2& aMessage)
+	{
+	TVwsViewIdAndMessageBuf viewToActivateBuf;
+	aMessage.ReadL(2,viewToActivateBuf);
+	TVwsViewIdAndMessage viewToActivate(viewToActivateBuf());
+	iViewIdToActivate=viewToActivate.iViewId;
+	if (iViewIdToActivate==TVwsViewId())
+		{	// Null view id, so ignore.
+		Complete(KErrNone);
+		}
+	else if (iServer.IsViewActive(iViewIdToActivate))
+		{
+		LOG4(CVwsLog::ELoud,_L("View \"%x,%x\" already active - aborting activation"),iViewIdToActivate.iAppUid.iUid,iViewIdToActivate.iViewUid.iUid);
+		Complete(KErrNone);
+		}
+	else
+		{
+		iClientMessage=CVwsClientMessage::NewL(viewToActivate.iCustomMessageId,viewToActivate.iCustomMessageLength,aMessage,3);
+		iScreenDeviceNotificationState=EViewActivationRequested;
+		
+		// Setting the iNewViewClientThreadId here indicates that if there are multiple sessions
+		// with the same app uid and we are switching views within one app then the one with the
+		// currently active view should be preferred
+		iNewViewClientThreadId = iServer.ActiveViewSession()->ClientThreadId();
+		RequestActivateNewView();
+		}
+	}
+
+#ifdef _DEBUG
+void CVwsServerEvent_ScreenDeviceChanged::Complete(TInt aError)
+#else
+void CVwsServerEvent_ScreenDeviceChanged::Complete(TInt /*aError*/)
+#endif // _DEBUG
+	{
+	LOG3(CVwsLog::ELoud,_L("Completed processing of screen device changed event with %d"),aError);
+	ReportEventProcessed();
+
+// Disable unused parameter warning under release builds
+#pragma warning (disable: 4100) 
+	}
+#pragma warning (default: 4100)
+
+void CVwsServerEvent_ScreenDeviceChanged::HandleAddedToQueue()
+	{
+	// display opaque intercepting window
+	iServer.MakeInterceptingWindowVisibleAndUpdateScreen();
+	}
+
+void CVwsServerEvent_ScreenDeviceChanged::HandleSessionRemoval(const TThreadId& aClientThreadId)
+	{
+	switch (iScreenDeviceNotificationState)
+		{
+	case EScreenDeviceChangeNotificationRequested:
+		{
+		CVwsSession* sessionWithActiveView=iServer.ActiveViewSession();
+		if(sessionWithActiveView && aClientThreadId==sessionWithActiveView->ClientThreadId())
+			{
+			LOG2(CVwsLog::ELoud,_L("Client with active view removed while screen device change request outstanding"));
+			RequestActivateSystemDefaultView();
+			iScreenDeviceNotificationState=EDefaultSystemViewActivationRequested;
+			}
+		}
+	case EViewActivationRequested:
+	case EDefaultSystemViewActivationRequested:
+		CVwsServerEvent_Activate::HandleSessionRemoval(aClientThreadId);
+		break;
+	case EPending:
+	default:
+		break;
+	}
+}
+
+void CVwsServerEvent_ScreenDeviceChanged::HandleTimeOut(CVwsEventTimer::TTimeOut /*aTimeOut*/)
+	{
+	LOG2(CVwsLog::ELoud,_L("CVwsServerEvent_ScreenDeviceChanged view event timer has passed client request time-out"));
+	switch (iScreenDeviceNotificationState)
+		{
+		case EScreenDeviceChangeNotificationRequested:
+			Complete(KErrNone);
+			break;
+
+		case EViewActivationRequested:
+		case EDefaultSystemViewActivationRequested:
+			CVwsServerEvent_Activate::HandleTimeOut(CVwsEventTimer::EClientRequestTimeOut);
+			break;
+
+		case EPending:
+		default:
+			break;
+		}
+	}
+
+//
+// CVwsServerEvent_DeactivateActiveView.
+//
+
+CVwsServerEvent_DeactivateActiveView::CVwsServerEvent_DeactivateActiveView(CVwsServer& aServer,CVwsEventQueue& aQueue,const RMessage2& aMessage,const TThreadId& aClientThreadId,TVwsCompleteRequest aCompleteRequest,CVwsEventTimer* aEventTimer)
+	: CVwsServerEvent(aServer,CVwsServerEvent::ENormal,aQueue),
+	iMessage(aMessage),
+	iClientThreadId(aClientThreadId),
+	iCompleteRequest(aCompleteRequest),
+	iEventTimer(aEventTimer)
+	{
+	}
+
+CVwsServerEvent_DeactivateActiveView::~CVwsServerEvent_DeactivateActiveView()
+	{
+	delete iEventTimer;
+	}
+
+void CVwsServerEvent_DeactivateActiveView::ProcessEventL()
+	{
+	LOG2(CVwsLog::ELoud,_L("Started processing of deactivate active view event"));
+	const TVwsViewId activeView(iServer.ActiveView());
+
+	//Check if the Cross Check UID is set, if it is then enable customised behaviour here
+	if(iServer.CrossCheckUid()!=KNullUid)
+		{
+		CVwsSession* self = iServer.SessionByThreadId(iClientThreadId);
+		CVwsSession* active = iServer.ActiveViewSession();
+		if (self != active)
+			{
+			LOG2(CVwsLog::ELoud,_L("Requested session does not have Active view, so ignoring deactivate active view event"));
+			if(iCompleteRequest==ECompleteRequest&& iServer.SessionByThreadId(iClientThreadId)!=NULL)
+				{
+				iMessage.Complete(KErrNone);
+				}
+			ReportEventProcessed();
+			return;
+			}
+		}
+
+	if (activeView.iAppUid.iUid)
+		{
+		TRAPD(err,RequestDeactivationL());
+		if (err)
+			{
+			Complete(err);
+			}
+		}
+	else
+		{
+		LOG2(CVwsLog::ELoud,_L("No active view, so ignoring deactivate active view event"));
+		Complete(KErrNone);
+		}
+	}
+
+#ifdef _DEBUG
+void CVwsServerEvent_DeactivateActiveView::RequestCompleted(TRequestType aType,TInt,const RMessage2&)
+#else
+void CVwsServerEvent_DeactivateActiveView::RequestCompleted(TRequestType /*aType*/,TInt,const RMessage2&)
+#endif // _DEBUG
+	{
+	switch (iState)
+		{
+		case EPending:
+			ASSERT(EFalse);
+			break;
+		case EDeactivationRequested:
+			ASSERT(aType==EDeactivation);
+			Complete(KErrNone);
+			break;
+		default:
+			ASSERT(EFalse);
+		}
+
+// Disable unused parameter warning under release builds
+#pragma warning (disable: 4100) 
+	}
+#pragma warning (default: 4100)
+
+void CVwsServerEvent_DeactivateActiveView::NowObserving(CVwsSessionEvent* aObserved)
+	{
+	if(iObserved)
+	    {
+	    iObserved->NullifyObserver();
+	    }
+	iObserved = aObserved;
+	}
+
+void CVwsServerEvent_DeactivateActiveView::NullifyObserved()
+	{
+	iObserved = NULL;	
+	}
+
+void CVwsServerEvent_DeactivateActiveView::RequestDeactivationL()
+	{
+	ASSERT(iState==EPending);
+
+	iEventTimer->Start(this,EFalse);
+
+	iActiveView=iServer.ActiveView();
+	CVwsSession* sessionWithActiveView=iServer.ActiveViewSession();
+	// If the session with currently active view is NULL, then the deactivation request is
+ 	// completed with KErrNotFound and the previously active view is activated.
+	if (sessionWithActiveView)
+ 		{
+ 		//EFalse always because the deactivation of view is requested by the application directly
+ 		sessionWithActiveView->RequestClientDeactivationL(*this,iActiveView,TVwsViewId(),EFalse);
+ 		iState=EDeactivationRequested;
+ 		}
+ 	else
+ 		{
+ 		LOG2(CVwsLog::ELoud,_L("Session with active view is NULL, so completing the deactivation request with KErrNotFound"));
+ 		User::Leave(KErrNotFound);
+ 		}
+	}
+
+void CVwsServerEvent_DeactivateActiveView::Complete(TInt aErr)
+	{
+	LOG3(CVwsLog::ELoud,_L("Completing deactivate active view event with %d"),aErr);
+	if (aErr)
+		{
+		iServer.HandleDeactivation(iActiveView,TVwsViewId());
+		}
+	iServer.ClearActiveView();
+	if(iCompleteRequest==ECompleteRequest&& iServer.SessionByThreadId(iClientThreadId)!=NULL)
+		{
+		iMessage.Complete(aErr);
+		}
+	ReportEventProcessed();
+	}
+
+void CVwsServerEvent_DeactivateActiveView::HandleSessionRemoval(const TThreadId& aClientThreadId)
+	{
+	TThreadId threadId(aClientThreadId);
+	if (iState==EDeactivationRequested)
+		{
+		CVwsSession* sessionWithActiveView=iServer.ActiveViewSession();
+		if (sessionWithActiveView && threadId==sessionWithActiveView->ClientThreadId())
+			{
+			LOG2(CVwsLog::ELoud,_L("Client with active view removed while session deactivation request outstanding"));
+			LOG2(CVwsLog::ELoud,_L("Client removal means deactivate active view event will not complete normally - deactivation cancelled"));
+			Complete(KErrCancel);
+			}
+		}
+	}
+
+void CVwsServerEvent_DeactivateActiveView::HandleTimeOut(CVwsEventTimer::TTimeOut aTimeOut)
+	{
+	if (aTimeOut==CVwsEventTimer::EServerEventTimeOut && iServer.IsServerEventTimeOutEnabled())
+		{
+		if (iState==EDeactivationRequested)
+			{
+			LOG3(CVwsLog::ENormal,_L("PANIC CLIENT \"%x\" for timing out activation view event - deactivation request was not completed"),iServer.ActiveView().iAppUid.iUid);
+			CVwsSession* sessionWithActiveView=iServer.ActiveViewSession();
+			if (sessionWithActiveView)
+				{
+				if(iServer.IsPriorityBoostBeforePanicEnabled())
+					{
+					if (iServer.InitializationFinished())
+						{
+						sessionWithActiveView->PanicClient(EVwsViewDeactivationEventTimeOut);
+						}
+					}
+				else
+					{
+					sessionWithActiveView->PanicClient(EVwsViewDeactivationEventTimeOut);
+					}
+				}
+			}
+		else
+			{
+			LOG4(CVwsLog::EQuiet,_L("Aborting deactivation of active view \"%x,%x\" - server event processing timed-out"),iServer.ActiveView().iAppUid.iUid,iServer.ActiveView().iViewUid.iUid);
+			Complete(KErrCancel);
+			}
+		}
+	else if (aTimeOut==CVwsEventTimer::EClientRequestTimeOut)
+			{
+			LOG2(CVwsLog::ELoud,_L("Deactivate active view event timer has passed client request time-out"));
+			if (iCompleteRequest==ECompleteRequest && iServer.SessionByThreadId(iClientThreadId)!=NULL)
+				{
+				LOG2(CVwsLog::ELoud,_L("Client request timed-out - silently completing request"));
+				iCompleteRequest=EDoNotCompleteRequest;
+				iMessage.Complete(KErrNone);
+				}
+			}
+		else if (aTimeOut==CVwsEventTimer::EIntermediateEventTimeOut) 
+           { 
+           if (iState==EDeactivationRequested) 
+               { 
+               iServer.BoostPriority(iServer.ActiveViewSession()); 
+               } 
+           }
+	}
+
+//
+// CVwsServerEvent_AppStart.
+//
+
+CVwsServerEvent_AppStart::CVwsServerEvent_AppStart(CVwsServer& aServer,CVwsEventQueue& aQueue,const RMessage2& aMessage,const TUid& aAppToStart,CVwsThreadWatcher* aThreadWatcher)
+	: CVwsServerEvent(aServer,CVwsServerEvent::ENormal,aQueue),iAppToStart(aAppToStart),iMessage(aMessage),iThreadWatcher(aThreadWatcher)
+	{
+	}
+
+CVwsServerEvent_AppStart::~CVwsServerEvent_AppStart()
+	{
+	delete iThreadWatcher;
+	}
+
+void CVwsServerEvent_AppStart::ProcessEventL()
+	{
+	LOG2(CVwsLog::ELoud,_L("Started processing of app start event"));
+
+	iSessionWithNewApp=iServer.SessionByUid(iAppToStart);
+	if (iSessionWithNewApp==NULL)
+		{
+		RequestAppStart();
+		}
+	else
+		{
+		Complete(KErrNone);
+		}
+	}
+
+void CVwsServerEvent_AppStart::HandleViewAdded(const TVwsViewId& aViewId, const TThreadId& aNewViewClientThreadId)
+	{
+	ASSERT(iState==EAppStartRequested);
+
+	if (aViewId.iAppUid==iAppToStart)
+		{
+		delete iThreadWatcher;
+		iThreadWatcher=NULL;
+		iServer.SetViewAdditionObserver(NULL);
+		ASSERT(iSessionWithNewApp==NULL);
+		iSessionWithNewApp=iServer.SessionByThreadIdAndAppUid(aNewViewClientThreadId,aViewId.iAppUid);
+		ASSERT(iSessionWithNewApp);
+		Complete(KErrNone);
+		}
+	}
+
+void CVwsServerEvent_AppStart::RequestAppStart()
+	{
+	iServer.SetViewAdditionObserver(this);
+	TThreadId appThreadId;
+	TInt err=iServer.StartApp(iAppToStart,appThreadId);
+	if (err)
+		{
+		LOG3(CVwsLog::EQuiet,_L("App start FAILED with %d"),err);
+		Complete(err);
+		}
+	else
+		{
+		iState=EAppStartRequested;
+		err=iThreadWatcher->StartWatching(appThreadId,TCallBack(&AppThreadWatcherCallBack,this));
+		if (err)
+			{
+			LOG3(CVwsLog::EQuiet,_L("App start FAILED with %d"),err);
+			Complete(err);
+			}
+		}
+	}
+
+TInt CVwsServerEvent_AppStart::AppThreadWatcherCallBack(TAny* aPtr)
+	// static
+	{
+	LOG2(CVwsLog::EQuiet,_L("App start FAILED with app client thread death"));
+	REINTERPRET_CAST(CVwsServerEvent_AppStart*,aPtr)->Complete(KErrCancel);
+	return 0;
+	}
+
+void CVwsServerEvent_AppStart::Complete(TInt aErr)
+	{
+	LOG3(CVwsLog::EQuiet,_L("App start event completed with %d"),aErr);
+	iServer.SetViewAdditionObserver(NULL);
+	iMessage.Complete(aErr);
+	ReportEventProcessed();
+	}