appfw/viewserver/client/VIEWCLI.CPP
changeset 0 2e3d3ce01487
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/appfw/viewserver/client/VIEWCLI.CPP	Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,1248 @@
+// 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:
+//
+
+#include <e32svr.h>
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include "vwsinternal.h"
+#include "viewclipartner.h"
+#include "vwsdefpartner.h"
+#endif //SYMBIAN_ENABLE_SPLIT_HEADERS
+
+#include "VIEWCLI.H"
+#include "VWSPRIV.H"
+#include "VWSAPPST.H"
+#include "VWSERVER.H"
+
+
+//
+// Constants.
+//
+
+const TUint KDefaultMessageSlots=5;
+const TInt KVwsDefaultScreenDeviceMode=0;
+const TInt KVwsServerStackSize=KDefaultStackSize;
+const TInt KVwsMinHeapSize=0x2000; 
+const TInt KVwsMaxHeapSize=0x1000000; 
+
+_LIT(KVwsViewServerThreadName,"ViewServerThread");
+_LIT(KVwsViewServerName,"!ViewServer");
+
+
+//
+// Macros.
+//
+
+#define CONNECT_AS_REQUIRED	TInt err=CheckCreateViewServerSession();	if (err) {return err;}
+
+
+//
+// Global functions.
+//
+
+
+
+//
+// RVwsSession.
+//
+
+RVwsSession::RVwsSession()
+	{
+	}
+
+TInt RVwsSession::Connect()
+	{
+	TInt ret=CreateSession(KVwsViewServerName,Version(),KDefaultMessageSlots);
+	if (ret == KErrNone)
+		SendReceive(EVwsAsynchronousMessageForServerToPanicClientWith,TIpcArgs(), iPanicStatus);
+	return ret;
+	}
+
+TVersion RVwsSession::Version() const
+	{
+	return(TVersion(KVwsMajorVersionNumber,KVwsMinorVersionNumber,KVwsBuildVersionNumber));
+	}
+
+TInt RVwsSession::Shutdown() const
+	{
+	return SendReceive(EVwsClose,TIpcArgs());
+	}
+
+TInt RVwsSession::AddView(const TVwsViewId& aViewId) const
+	{
+	const TPckgC<TVwsViewId> viewId(aViewId);
+	return SendReceive(EVwsAddView,TIpcArgs(&viewId));
+	}
+
+TInt RVwsSession::SetClientRequestTimeOut(TTimeIntervalMicroSeconds32 aDuration) const
+	{
+	return SendReceive(EVwsSetClientRequestTimeOut,TIpcArgs(aDuration.Int()));
+	}
+
+TInt RVwsSession::SetServerEventTimeOut(TTimeIntervalMicroSeconds32 aDuration) const
+	{
+	return SendReceive(EVwsSetServerEventTimeOut,TIpcArgs(aDuration.Int()));
+	}
+
+TInt RVwsSession::EnableServerEventTimeOut(TBool aEnable) const
+	{
+	return SendReceive(EVwsEnableServerEventTimeOut,TIpcArgs(aEnable));
+	}
+
+TInt RVwsSession::SetSystemDefaultView(const TVwsViewId& aViewId,TInt aMode) const
+	{
+	const TPckgC<TVwsViewId> viewId(aViewId);
+	return SendReceive(EVwsSetSystemDefaultView,TIpcArgs(&viewId,aMode));
+	}
+
+TInt RVwsSession::GetSystemDefaultView(TVwsViewId& aViewId)
+	{
+	TPckg<TVwsViewId> viewId(aViewId);
+	return SendReceive(EVwsGetSystemDefaultView,TIpcArgs(&viewId));
+	}
+
+TInt RVwsSession::RemoveView(const TVwsViewId& aViewId) const
+	{
+	const TPckgC<TVwsViewId> viewId(aViewId);
+	return SendReceive(EVwsRemoveView,TIpcArgs(&viewId));
+	}
+
+void RVwsSession::RequestViewEvent(TVwsViewEventBuf& aViewEventBuf,TInt aLastError,TRequestStatus& aStatus) const
+	{
+	SendReceive(EVwsRequestViewEvent,TIpcArgs(&aViewEventBuf,aLastError,0,0),aStatus);
+	}
+	
+	void RVwsSession::RequestViewEvent(TVwsViewEventBuf& aViewEventBuf,TInt aLastError,const TVwsViewIdAndMessageBuf& aViewActivationBuf,const TDesC8& aMessage,TRequestStatus& aStatus) const
+	{
+	SendReceive(EVwsRequestViewEvent,TIpcArgs(&aViewEventBuf,aLastError,&aViewActivationBuf,&aMessage),aStatus);
+	}
+
+TInt RVwsSession::RequestViewEventCancel() const
+	{
+	return SendReceive(EVwsRequestViewEventCancel,TIpcArgs());
+	}
+
+void RVwsSession::ActivateView(const TVwsViewId& aViewId,TUid aCustomMessageId,const TDesC8& aCustomMessage,TRequestStatus& aStatus, TInt aCustomControl)
+	{
+	iActivateViewId=aViewId;
+	iCustomMessage.Set(aCustomMessage);
+	SendReceive(EVwsActivateView,TIpcArgs(&iActivateViewId,aCustomMessageId.iUid,&iCustomMessage,aCustomControl),aStatus);
+	}
+
+TInt RVwsSession::ActivateView(const TVwsViewId& aViewId,TUid aCustomMessageId,const TDesC8& aCustomMessage, TInt aCustomControl)
+	{
+	const TPckgC<TVwsViewId> viewId(aViewId);
+	return SendReceive(EVwsCreateActivateViewEvent,TIpcArgs(&viewId,aCustomMessageId.iUid,&aCustomMessage,aCustomControl));
+	}
+
+TInt RVwsSession::RequestCustomMessage(TDes8& aMessageBuf) const
+	{
+	return SendReceive(EVwsRequestCustomMessage,TIpcArgs(&aMessageBuf));
+	}
+
+TInt RVwsSession::StartApp(TUid aAppToStart) const
+	{
+	return SendReceive(EVwsStartApp,TIpcArgs(aAppToStart.iUid));
+	}
+
+void RVwsSession::DeactivateActiveView(TRequestStatus& aStatus) const
+	{
+	SendReceive(EVwsDeactivateActiveView,TIpcArgs(),aStatus);
+	}
+
+TInt RVwsSession::DeactivateActiveView() const
+	{
+	return SendReceive(EVwsCreateDeactivateViewEvent,TIpcArgs());
+	}
+void RVwsSession::DeactivateActiveViewIfOwnerMatch(TRequestStatus& aStatus) const
+ 	{
+ 	SendReceive(EVwsDeactivateActiveViewIfOwnerMatch,TIpcArgs(), aStatus);
+ 	}
+ 
+TInt RVwsSession::DeactivateActiveViewIfOwnerMatch() const
+ 	{
+ 	return SendReceive(EVwsDeactivateActiveViewIfOwnerMatch,TIpcArgs());
+ 	}
+ 
+
+
+TInt RVwsSession::NotifyNextDeactivation(const TVwsViewId& aViewId) const
+	{
+	const TPckgC<TVwsViewId> viewId(aViewId);
+	return SendReceive(EVwsNotifyNextDeactivation,TIpcArgs(&viewId));
+	}
+
+TInt RVwsSession::NotifyNextActivation(const TVwsViewId& aViewId) const
+	{
+	const TPckgC<TVwsViewId> viewId(aViewId);
+	return SendReceive(EVwsNotifyNextActivation,TIpcArgs(&viewId));
+	}
+
+TInt RVwsSession::GetPriority()	
+	{
+	TInt eventHandlerPriority = CActive::EPriorityStandard;
+	TPckg<TInt> package(eventHandlerPriority);
+	TInt err = SendReceive(EVwsPriority,TIpcArgs(&package));
+	if (err != KErrNone)
+		{
+		return CActive::EPriorityStandard;
+		}
+	return eventHandlerPriority;
+	}
+ 
+TInt RVwsSession::CheckSourceOfViewSwitch(TBool& aResult,const TSecurityPolicy& aSecurityPolicy,const char* aDiagnostic) const
+	{
+	const TPckgC<TSecurityPolicy> securityPolicy(aSecurityPolicy);
+	TBool result;
+	TPckg<TBool> resultPckg(result);
+	TIpcArgs ipcArgs(&securityPolicy,NULL,&resultPckg);
+	if (aDiagnostic == KSuppressPlatSecDiagnosticMagicValue)
+    	{
+    	ipcArgs.Set(1, reinterpret_cast<TInt>(KSuppressPlatSecDiagnosticMagicValue));
+    	}
+  	else if (aDiagnostic!=NULL)
+	    	{
+	    	TPtrC8 diagnostic(TPtrC8(REINTERPRET_CAST(const TUint8*,aDiagnostic)));
+	    	ipcArgs.Set(1,&diagnostic);
+	    	}
+
+	const TInt ret=SendReceive(EVwsCheckSourceOfViewSwitch,ipcArgs);
+	if (ret==KErrNone)
+		{
+		aResult=result;
+		}
+	return ret;
+	}
+
+TInt RVwsSession::EnableServerBlankScreen(TBool aEnable) const
+	{
+	return SendReceive(EVwsEnableServerBlankScreen,TIpcArgs(aEnable));
+	}
+
+TInt RVwsSession::SetProtected(TBool aEnable) const
+	{
+	return SendReceive(EVwsSetProtected,TIpcArgs(aEnable));
+	}
+
+TInt RVwsSession::SetCrossCheckUid(const TUid& aCrossCheckUid)
+	{
+	return SendReceive(EVwsSetCrossCheckUid,TIpcArgs(aCrossCheckUid.iUid));
+	}
+	
+TInt RVwsSession::SetWindowBackgroundColor(const TRgb& aBgColor)
+	{
+	return SendReceive(EVwsSetWindowBackgroundColor, TIpcArgs(aBgColor.Internal()));
+	}
+
+TInt RVwsSession::GetCurrentActiveViewInSystem(TVwsViewId& aActiveViewId)
+	{
+	TPckg<TVwsViewId> pckgViewId(aActiveViewId);
+	return SendReceive(EVwsCurrentActiveViewId, TIpcArgs(&pckgViewId));
+	}
+
+//
+// CVwsSessionEventHandler.
+//
+//The priority is read from the resource file
+
+CVwsSessionEventHandler::CVwsSessionEventHandler(MVwsSessionWrapperObserver& aObserver,RVwsSession& aViewServer,TInt aPriority)
+	: CActive(aPriority),iObserver(aObserver),iVwsSession(aViewServer)
+ 	{
+	CActiveScheduler::Add(this);
+	Queue();
+	}
+
+CVwsSessionEventHandler::~CVwsSessionEventHandler()
+	{
+	Cancel();
+	}
+
+void CVwsSessionEventHandler::Queue()
+	{
+	ASSERT(!IsActive());
+
+	if (iDoActivationNextQueue)
+		{
+		iDoActivationNextQueue=EFalse;
+		iVwsSession.RequestViewEvent(iViewEventBuf,iLastError,iViewActivationBuf,iCustomMessage,iStatus);
+		}
+	else
+		{
+		iVwsSession.RequestViewEvent(iViewEventBuf,iLastError,iStatus);
+		}
+	SetActive();
+	}
+
+void CVwsSessionEventHandler::OnNextQueueActivateView(const TVwsViewIdAndMessage& aViewIdAndMessage)
+	{
+	iViewActivationBuf=aViewIdAndMessage;
+	iCustomMessage.Set(aViewIdAndMessage.iCustomMessage);
+	iDoActivationNextQueue=ETrue;
+	}
+
+void CVwsSessionEventHandler::RunL()
+	{
+	TRAP(iLastError,iObserver.HandleViewEventL(iViewEventBuf()));
+	Queue();
+	}
+
+void CVwsSessionEventHandler::DoRunL()
+	{
+	RunL();
+	}
+
+void CVwsSessionEventHandler::DoCancel()
+	{
+	iVwsSession.RequestViewEventCancel();
+	}
+
+
+//
+// CVwsSessionWrapper.
+//
+
+
+EXPORT_C CVwsSessionWrapper* CVwsSessionWrapper::NewL()
+/**
+Creates a new CVwsSessionWrapper object.
+
+The object returned by this function cannot be used to add new views or request 
+notification of view activations or deactivations. To create an instance without these
+limitations, an MVwsSessionWrapperObserver must be specified.
+
+@return A pointer to the new CVwsSessionWrapper object.
+ */
+	{
+	CVwsSessionWrapper* self=NewLC();
+	CleanupStack::Pop();
+	return self;
+	}
+
+EXPORT_C CVwsSessionWrapper* CVwsSessionWrapper::NewLC()
+/**
+Creates a new CVwsSessionWrapper object, leaving it on the cleanup stack
+
+The object returned by this function cannot be used to add new views or request 
+notification of view activations or deactivations. To create an instance without these
+limitations, an MVwsSessionWrapperObserver must be specified.
+
+@return A pointer to the new CVwsSessionWrapper object.
+ */
+	{
+	CVwsSessionWrapper* self=new(ELeave) CVwsSessionWrapper();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+EXPORT_C CVwsSessionWrapper* CVwsSessionWrapper::NewL(MVwsSessionWrapperObserver& aObserver)
+/**
+Creates a new CVwsSessionWrapper object.
+
+@param aObserver An implementation of MVwsSessionWrapperObserver.
+                 The session observer should handle server events such as view
+                 activation/deactivation requests for views owned by this session
+                 and notifications of view activations/deactivations that have been
+                 requested.
+
+@return A pointer to the new CVwsSessionWrapper object.
+ */
+	{
+	CVwsSessionWrapper* self=NewLC(aObserver);
+	CleanupStack::Pop();
+	return self;
+	}
+
+EXPORT_C CVwsSessionWrapper* CVwsSessionWrapper::NewLC(MVwsSessionWrapperObserver& aObserver)
+/**
+Creates a new CVwsSessionWrapper object, leaving it on the cleanup stack.
+
+@param aObserver An implementation of MVwsSessionWrapperObserver.
+                 The session observer should handle server events such as view
+                 activation/deactivation requests for views owned by this session
+                 and notifications of view activations/deactivations that have been
+                 requested.
+
+@return A pointer to the new CVwsSessionWrapper object.
+ */
+	{
+	CVwsSessionWrapper* self=new(ELeave) CVwsSessionWrapper(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+EXPORT_C CVwsSessionWrapper::~CVwsSessionWrapper()
+	{
+	delete iViewEventHandler;
+	if (iVwsSession)
+		{
+		iVwsSession->Close();
+		delete iVwsSession;
+		}
+	}
+
+// static
+EXPORT_C TInt CVwsSessionWrapper::StartViewServer(MVwsAppStarter& aAppStarter)
+/**
+Starts the view server, spawning a new thread in which the server will run.
+ 
+Takes a reference to the implementation of the MVwsAppStarter interface aAppStarter
+which it will share from the heap and which should be for the exclusive use of the view
+server only.
+
+@param aAppStarer An implementation of MVwsAppStarter that the server can use for
+                  starting applications.
+
+@return A system-wide error code if the server cannot be started or is already running.
+ */
+	{
+	TFindServer findServer(KVwsViewServerName);
+	TFullName name;
+	if (findServer.Next(name)==KErrNone)
+	    {
+	    return KErrAlreadyExists;
+	    }
+
+	RThread viewServerThread;
+	SVwsCommandLine comLine;
+	comLine.iAppStarter=&aAppStarter;
+    TInt err = viewServerThread.Create(KVwsViewServerThreadName,ViewServerThreadStart,KVwsServerStackSize,KVwsMinHeapSize,KVwsMaxHeapSize,&comLine,EOwnerThread);
+	if (err==KErrNone)
+        {
+		TRequestStatus requestStatus;
+		viewServerThread.Rendezvous(requestStatus);
+
+		viewServerThread.Resume();
+		
+		User::WaitForRequest(requestStatus);
+		err=requestStatus.Int();
+		viewServerThread.Close();
+		}
+
+	return err;
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::ShutdownViewServer()
+/**
+Shut down the view server. 
+
+Establishes a connection to the view server if necessary.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+ */
+	{
+	CONNECT_AS_REQUIRED
+	return iVwsSession->Shutdown();
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::AddView(const TVwsViewId& aViewId)
+/**
+Adds the view to the list maintained by the view server.
+
+Establishes a connection to the view server if necessary.
+
+@param aViewId The view to be added to the view server's list.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+ */	
+	{
+	CONNECT_AS_REQUIRED
+	return iVwsSession->AddView(aViewId);
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::RemoveView(const TVwsViewId& aViewId) const
+/**
+Removes a view from the list maintained by the view server.
+
+@param aViewId The view to be removed from the view server's list.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+
+@panic USER 0 if a connection to the view server has not previously been established.
+ */		
+	{
+	ASSERT(iVwsSession);
+	return iVwsSession->RemoveView(aViewId);
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::SetSystemDefaultView(const TVwsViewId& aViewId,TInt aMode)
+/**
+Sets the system default view for a specific screen device mode.
+
+The system default view is the view used when an unrecoverable error in view activation occurs
+or when an application exits.
+
+Establishes a connection to the view server if necessary.
+
+@param aViewId The view to use as the system default view in the specified
+               screen device mode
+@param aMode The screen device mode that should use aViewId as the system
+             default view. Valid values for aMode are those listed in the Wserv
+             initialization file.
+             
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+ */
+	{
+	CONNECT_AS_REQUIRED
+	return iVwsSession->SetSystemDefaultView(aViewId,aMode);
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::SetSystemDefaultView(const TVwsViewId& aViewId)
+/**
+Sets the system default view for the default screen device mode.
+
+Establishes a connection to the view server if necessary.
+
+@param aViewId The view to use as the system default view in the default screen
+               device mode
+             
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+ */
+	{
+	return SetSystemDefaultView(aViewId,KVwsDefaultScreenDeviceMode);
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::GetSystemDefaultView(TVwsViewId& aViewId)
+/**
+Gets the system default view for the current screen device mode
+
+@param aViewId The ViewId of the system default view will be returned in this
+               paramater.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+ */
+	{
+	return iVwsSession->GetSystemDefaultView(aViewId);
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::SetClientRequestTimeOut(TTimeIntervalMicroSeconds32 aDuration)
+/**
+Sets the time out duration for client requests.
+
+If the time taken to process a view event exceeds this limit any outstanding
+client request will silently be completed.
+
+Establishes a connection to the view server if necessary.
+
+@param aDuration The duration of the timeout, in microseconds.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+
+@since App-Framework_6.1
+ */
+	{
+	CONNECT_AS_REQUIRED
+	return iVwsSession->SetClientRequestTimeOut(aDuration);
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::SetServerEventTimeOut(TTimeIntervalMicroSeconds32 aDuration)
+/**
+Sets the time out duration for server events.
+
+If the time taken to process a view event exceeds this limit the server event
+will be completed. If a client is preventing the view event from completing
+the server will panic that client.
+
+Establishes a connection to the view server if necessary.
+
+@param aDuration The duration of the timeout, in microseconds.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+
+@since App-Framework_6.1
+ */
+	{
+	CONNECT_AS_REQUIRED
+	return iVwsSession->SetServerEventTimeOut(aDuration);
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::EnableServerEventTimeOut(TBool aEnable)
+/**
+Enables or disables the server event time out.
+
+This may be called, for example, when debugging on target hardware since server
+event processing can be interrupted indefinitely by the debugger.
+
+Establishes a connection to the view server if necessary.
+
+@param aEnable The timeout is enabled if aEnable is set to ETrue, and disabled
+               if aEnable is set to EFalse
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+
+@since App-Framework_6.1
+ */
+	{
+	CONNECT_AS_REQUIRED
+	return iVwsSession->EnableServerEventTimeOut(aEnable);
+	}
+
+/**
+Sets the session default view for the screen device mode aMode to aViewId.
+Valid values for aMode are those listed in the Wserv initialisation file.
+
+As of R6 this function has no effect.
+
+@deprecated
+
+@return KErrNone.
+ */
+EXPORT_C TInt CVwsSessionWrapper::SetDefaultView(const TVwsViewId& /*aViewId*/,TInt /*aMode*/) const
+	{
+	return KErrNone;
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::SetDefaultView(const TVwsViewId& aViewId) const
+/**
+Overloaded member funtion that sets the session default view for the
+default screen device mode to aViewId.
+
+As of R6 this funtion has no effect.
+
+@deprecated
+
+@return KErrNone.
+ */
+	{
+	return SetDefaultView(aViewId,KVwsDefaultScreenDeviceMode);
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::ActivateView(const TVwsViewId& aViewId,TUid aCustomMessageId,const TDesC8& aCustomMessage)
+/**
+Activates a view.
+
+Supplies the narrow message text descriptor aCustomMessage for the message type
+identified by aCustomMessageId to the server.
+
+Establishes a connection to the view server if necessary.
+Starts the application which owns the view if necessary.
+
+Once a new view is activated the current view is deactivated and the new view
+is marked as current.
+
+If this thread has an active environment the method returns when view
+activation completes. Otherwise the method returns
+immediately after creating an activation event in the view server.
+
+@param aViewId The view to activate
+@param aCustomMessageId The message type being passed in aCustomMessage.
+@param aCustomMessage  A custom message for the view being activated.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+ */			
+	{
+	return ActivateView(aViewId, aCustomMessageId, aCustomMessage, 0);
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::ActivateView(const TVwsViewId& aViewId,TUid aCustomMessageId,const TDesC8& aCustomMessage, TInt aCustomControl)
+	{
+	CONNECT_AS_REQUIRED
+
+	if (!IsSchedulerRunning())
+		{
+		return iVwsSession->ActivateView(aViewId,aCustomMessageId,aCustomMessage, aCustomControl);
+		}
+	else
+		{
+		TRequestStatus status;
+		iVwsSession->ActivateView(aViewId,aCustomMessageId,aCustomMessage,status, aCustomControl);
+		TInt error=KErrNone;
+		for (;;)
+			{
+			if (iViewEventHandler)
+				{
+				User::WaitForRequest(status, iViewEventHandler->iStatus);
+				}
+			else
+				{
+				User::WaitForRequest(status);
+				}
+			if (status!=KRequestPending)
+				break;
+			if (iViewEventHandler && iViewEventHandler->iStatus!=KRequestPending)
+				{
+				// Set the event handler active object to inactive to avoid it running
+				// a second time if the DoRunL call results in a new active scheduler
+				// loop being started.
+				TRequestStatus* eventHandlerStatus = &iViewEventHandler->iStatus;
+				User::RequestComplete(eventHandlerStatus, iViewEventHandler->iStatus.Int());
+				iViewEventHandler->Cancel();
+				TRAP(error,iViewEventHandler->DoRunL(););	// Run event handler directly and request new view event.
+				if (error != KErrNone)
+					{
+					break;
+					}
+				}
+			}
+
+		return (error != KErrNone) ? error : status.Int();
+		}
+	}
+
+EXPORT_C void CVwsSessionWrapper::ActivateView(
+									const TVwsViewId& aViewId,
+									TUid aCustomMessageId,
+									const TDesC8& aCustomMessage,
+									TRequestStatus& aStatus)
+/**
+Activates a view asynchronously.
+
+Supplies the narrow message text descriptor aCustomMessage for the message type
+identified by aCustomMessageId to the server.
+
+Establishes a connection to the view server if necessary.
+Starts the application which owns the view if necessary.
+
+Once a new view is activated the current view is deactivated and the new view
+is marked as current.
+
+This function will return immediately
+
+@param aViewId The view to activate
+@param aCustomMessageId The message type being passed in aCustomMessage.
+@param aCustomMessage  A custom message for the view being activated.
+@param aStatus A TRequestStatus for the view activation. The request will be
+               completed when the the view has been activated or when the
+               view activation has failed.
+
+@return KErrNone if the request was dispatched successfully, otherwise one of
+        the system-wide error codes.
+ */
+	{
+	ActivateView(aViewId, aCustomMessageId, aCustomMessage, aStatus, 0);
+	}
+	
+EXPORT_C void CVwsSessionWrapper::ActivateView(
+									const TVwsViewId& aViewId,
+									TUid aCustomMessageId,
+									const TDesC8& aCustomMessage,
+									TRequestStatus& aStatus, TInt aCustomControl)
+	{
+	TInt res = CheckCreateViewServerSession();
+	if (res != KErrNone)
+		{
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete(status, res);
+		return;
+		}
+	iVwsSession->ActivateView(aViewId, aCustomMessageId, aCustomMessage, aStatus, aCustomControl);
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::CreateActivateViewEvent(const TVwsViewId& aViewId,TUid aCustomMessageId,const TDesC8& aCustomMessage)
+/**
+Creates an event to be processed to activate the view identified by aViewId and
+returns without waiting for the activation to complete. Passes the view the
+message text descriptor aCustomMessage for a message of type aCustomMessageId.
+
+Note that this method may return without error but the activation may subsequently fail.
+
+Establishes a connection to the view server if necessary.
+
+@param aViewId The view to activate
+@param aCustomMessageId The message type being passed in aCustomMessage.
+@param aCustomMessage  A custom message for the view being activated.
+
+@return KErrNone if the request was dispatched successfully, otherwise one of
+        the system-wide error codes.
+ */
+	{
+	return CreateActivateViewEvent(aViewId, aCustomMessageId, aCustomMessage, 0);
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::CreateActivateViewEvent(const TVwsViewId& aViewId,TUid aCustomMessageId,const TDesC8& aCustomMessage, TInt aCustomControl)
+	{
+	CONNECT_AS_REQUIRED
+
+	return iVwsSession->ActivateView(aViewId, aCustomMessageId, aCustomMessage, aCustomControl);
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::ActivateViewViaViewEvent(const TVwsViewIdAndMessage& aViewIdAndMessage)
+/**
+Activates the view identified in aViewIdAndMessage on the next queue of the
+session's view event handler. This activation path should be used for
+activation requests that come via view events.
+
+For example, a screen device change will generate a view event in the active
+view. The active view is then responsible for choosing the next view to
+activate. Using this activation path ensures that the view activation is
+processed immediately by the server.
+
+Establishes a connection to the view server if necessary.
+
+@param aViewIdAndMessage An object encapsulating the view to activate and
+                         the message to be passed to it with the activation
+                         event
+
+@return KErrNone
+*/
+	{
+	CONNECT_AS_REQUIRED
+
+	if (iViewEventHandler)
+		{
+		iViewEventHandler->OnNextQueueActivateView(aViewIdAndMessage);
+		}
+	return KErrNone;
+	}
+
+/**
+Retrives the custom message contents for the event currently being processsed
+from the server.
+
+This method is typically called when the MVwsSessionObserver is notified that
+it should activate a new view.
+
+@param aMessageBufPtr The narrow descriptor for the custom message contents to
+                      be written to.
+ 
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+
+@panic USER 0 If a connection to the view server has not previously been established
+ */
+EXPORT_C TInt CVwsSessionWrapper::RequestCustomMessage(TDes8& aMessageBufPtr) const
+	{
+	ASSERT(iVwsSession);
+	return iVwsSession->RequestCustomMessage(aMessageBufPtr);
+	}
+
+/**
+Queues an asynchronous view server event request. This method should be called
+by the active scheduler so that an outstanding request for view server event
+notification is maintained. The view server interprets the first queue made by
+a session as the sign that the session application is up and runnning.
+
+This method is now deprecated becasue the requests are now automatically queued
+by CVwsSessionWrapper.
+
+@deprecated
+ */
+EXPORT_C void CVwsSessionWrapper::QueueAsyncRequest()
+	{
+	if (iViewEventHandler)
+		{
+		iViewEventHandler->Queue();
+		}
+	}
+
+/**
+Starts the application with Uid aAppToStart.
+
+Establishes a connection to the view server if necessary.
+
+The request is queued in the server and processed in turn. The application will
+be started by a call to the implementation of the MVwsAppStarter interface that
+is provided at server start up. 
+
+This method provides an alternative to apparc for starting apps on systems
+where use of the view server is preferred to use of the apparc server.
+ 
+
+@param aAppToStart The Uid of the app that should be started.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+ */
+EXPORT_C TInt CVwsSessionWrapper::StartApp(TUid aAppToStart)
+	{
+	CONNECT_AS_REQUIRED
+	return iVwsSession->StartApp(aAppToStart);
+	}
+
+/**
+Note: DeactivateActiveViewIfOwnerMatch should be used instead of this function
+      where it is appropriate.
+      
+Deactivates the active view. This is required before exiting an application
+with an active view.
+
+Establishes a connection to the view server if necessary.
+
+If this thread has an active environment the method returns when view
+deactivation completes. Otherwise the method returns immediately after creating
+a deactivation event in the view server.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+
+@see CVwsSessionWrapper::DeactivateActiveViewIfOwnerMatch
+*/
+EXPORT_C TInt CVwsSessionWrapper::DeactivateActiveView()
+	{
+	CONNECT_AS_REQUIRED
+
+	if (!IsSchedulerRunning())
+		{
+		return iVwsSession->DeactivateActiveView();
+		}
+	else
+		{
+		TRequestStatus status;
+		iVwsSession->DeactivateActiveView(status);
+		TInt error=KErrNone;
+		for (;;)
+			{
+			if (iViewEventHandler)
+				{
+				User::WaitForRequest(status, iViewEventHandler->iStatus);
+				}
+			else
+				{
+				User::WaitForRequest(status);
+				}
+			if (status!=KRequestPending)
+				break;
+			if (iViewEventHandler && iViewEventHandler->iStatus!=KRequestPending)
+				{
+				// Set the event handler active object to inactive to avoid it running
+				// a second time if the DoRunL call results in a new active scheduler
+				// loop being started.
+				TRequestStatus* eventHandlerStatus = &iViewEventHandler->iStatus;
+				User::RequestComplete(eventHandlerStatus, iViewEventHandler->iStatus.Int());
+				iViewEventHandler->Cancel();
+				TRAP(error,iViewEventHandler->DoRunL(););	// Run event handler directly and request new view event.
+				if (error != KErrNone)
+					{
+					break;
+					}
+				}
+			}
+		return (error != KErrNone) ? error : status.Int();
+		}
+	}
+
+/**
+Deactivates the active view, but only if the active view is owned by this session.
+ This is required before exiting an application with an active view.
+ 
+ Establishes a connection to the view server if necessary.
+ 
+ If this thread has an active environment the method returns when view
+ deactivation completes. Otherwise the method returns immediately after creating
+ a deactivation event in the view server.
+ 
+ @return KErrNone if the active view was deactivated or is owned by another session, otherwise one of the system-wide error codes. 
+  */
+ EXPORT_C TInt CVwsSessionWrapper::DeactivateActiveViewIfOwnerMatch()
+ 	{
+ 	CONNECT_AS_REQUIRED
+ 
+ 	if (!IsSchedulerRunning())
+ 		{
+ 		return iVwsSession->DeactivateActiveViewIfOwnerMatch();
+		}
+ 	else
+ 		{
+ 		TRequestStatus status;
+ 		iVwsSession->DeactivateActiveViewIfOwnerMatch(status);
+ 		TInt error=KErrNone;
+ 		for (;;)
+ 			{
+ 			if (iViewEventHandler)
+ 				{
+ 				User::WaitForRequest(status, iViewEventHandler->iStatus);
+ 				}
+ 			else
+ 				{
+ 				User::WaitForRequest(status);
+ 				}
+ 			if (status!=KRequestPending)
+ 				break;
+ 			if (iViewEventHandler && iViewEventHandler->iStatus!=KRequestPending)
+ 				{
+				// Set the event handler active object to inactive to avoid it running
+ 				// a second time if the DoRunL call results in a new active scheduler
+ 				// loop being started.
+ 				TRequestStatus* eventHandlerStatus = &iViewEventHandler->iStatus;
+ 				User::RequestComplete(eventHandlerStatus, iViewEventHandler->iStatus.Int());
+ 				iViewEventHandler->Cancel();
+ 				TRAP(error,iViewEventHandler->DoRunL(););	// Run event handler directly and request new view event.
+ 				if (error != KErrNone)
+ 					{
+ 					break;
+ 					}
+ 				}
+ 			}
+ 		return (error != KErrNone) ? error : status.Int();
+ 		}
+ 	}
+ 
+/**
+
+Requests that the next deactivation of the view identified by aViewId be
+notified to this session. The request is cleared after the next notification.
+Only the last made notification request is honoured.
+
+For example, can be used when a screensaver view is deactivated by new user
+activity to reset the system state.
+
+Establishes a connection to the view server if necessary.
+
+@param aViewId The view to monitor for deactivation.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+ */
+EXPORT_C TInt CVwsSessionWrapper::NotifyNextDeactivation(const TVwsViewId& aViewId)
+	{
+	CONNECT_AS_REQUIRED
+	return iVwsSession->NotifyNextDeactivation(aViewId);
+	}
+
+/**
+Requests that the next deactivation of any view be notified to this session.
+The request is cleared after the next notification. Only the last made
+notification request is honoured.
+
+Establishes a connection to the view server if necessary.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+ */
+EXPORT_C TInt CVwsSessionWrapper::NotifyNextDeactivation()
+	{
+	return NotifyNextDeactivation(KNullViewId);
+	}
+
+/**
+Requests that the next activation of the view identified by aViewId be
+notified to this session. The request is cleared after the next notification.
+Only the last made notification request is honoured.
+
+This allows any client to track the system current active state.
+
+Establishes a connection to the view server if necessary.
+
+@param aViewId The view to monitor for activation.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+ */
+EXPORT_C TInt CVwsSessionWrapper::NotifyNextActivation(const TVwsViewId& aViewId)
+	{
+	CONNECT_AS_REQUIRED
+	return iVwsSession->NotifyNextActivation(aViewId);
+	}
+
+/**
+Requests that the next activation of any view be notified to this session. The
+request is cleared after the next notification. Only the last made notification
+request is honoured.
+
+Establishes a connection to the view server if necessary.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+ */
+EXPORT_C TInt CVwsSessionWrapper::NotifyNextActivation()
+	{
+	return NotifyNextActivation(KNullViewId);
+	}
+
+/**
+Tests whether the thread that requested the current view switch satisfies a
+security policy. This function can only be called from the thread of the
+session that owns the view being activated, and only during the activation of
+a view.
+
+Establishes a connection to the view server if necessary.
+
+@param aResult If the requesting thread satisfies the security policy, aResult
+               will be set to ETrue, otherwise it will be set to EFalse.
+               If this function does not complete successfully, aResult is
+               undefined.
+@param aSecurityPolicy The security policy to check the requesting thread
+                       against.
+
+@return KErrNone if successful, KErrUnknown if this function is called from the
+        wrong session or at the wrong time, otherwise one of the system-wide
+        error codes.
+
+@see CCoeAppUi::CheckSourceOfViewSwitchL
+ */
+EXPORT_C TInt CVwsSessionWrapper::CheckSourceOfViewSwitch(TBool& aResult,const TSecurityPolicy& aSecurityPolicy,const char* aDiagnostic)
+	{
+	CONNECT_AS_REQUIRED
+	return iVwsSession->CheckSourceOfViewSwitch(aResult,aSecurityPolicy,aDiagnostic);
+	}
+
+/**
+Enables or disables screen blanking between screen device changes.
+
+If screen blanking is enabled, the screen will be covered by a solid window. The color of this blanking window
+would be as set in CVwsSessionWrapper::SetWindowBackgroundColor method if its used, otherwise by default the 
+color would be solid-white.
+@see CVwsSessionWrapper::SetWindowBackgroundColor
+
+Establishes a connection to the view server if necessary.
+
+@param aEnable If aEnable is set to ETrue, screen blanking will take place as
+               described above, if aEnable is set to EFalse, screen blanking
+               will not happen.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+ */
+EXPORT_C TInt CVwsSessionWrapper::EnableServerBlankScreen(TBool aEnable)
+	{
+	CONNECT_AS_REQUIRED
+	return iVwsSession->EnableServerBlankScreen(aEnable);
+	}
+
+/**
+Enable or disable protection from external view switches for this session.
+
+Views owned by protected sessions can only be activated by view activation
+requests originating from the same session. Activation requests originating
+from other sessions will cause a second instance of the application providing
+the requested view to be started.
+By default, sessions are not protected from external view switches.
+ 
+Establishes a connection to the view server if necessary.
+
+@param aEnable If set to ETrue, this session's views will be protected from
+               external view switches. If set to EFalse, they will have no such
+               protection.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+ */
+EXPORT_C TInt CVwsSessionWrapper::EnableExternalViewSwitches(TBool aEnable)
+	{
+	CONNECT_AS_REQUIRED
+	return iVwsSession->SetProtected(!aEnable);
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::SetCrossCheckUid(const TUid& aCrossCheckUid)
+	{
+	CONNECT_AS_REQUIRED
+	return iVwsSession->SetCrossCheckUid(aCrossCheckUid);
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::SetWindowBackgroundColor(const TRgb& aBgColor)
+	{
+	CONNECT_AS_REQUIRED
+	return iVwsSession->SetWindowBackgroundColor(aBgColor);
+	}
+
+EXPORT_C TInt CVwsSessionWrapper::GetCurrentActiveViewInSystem(TVwsViewId& aActiveViewId)
+	{
+	CONNECT_AS_REQUIRED
+	return iVwsSession->GetCurrentActiveViewInSystem(aActiveViewId);
+	}
+
+CVwsSessionWrapper::CVwsSessionWrapper()
+	{
+	}
+
+CVwsSessionWrapper::CVwsSessionWrapper(MVwsSessionWrapperObserver& aObserver) : iObserver(&aObserver)
+	{
+	}
+
+void CVwsSessionWrapper::ConstructL()
+	{
+	}
+
+TBool CVwsSessionWrapper::IsSchedulerRunning()
+	{
+	if (iViewEventHandler)
+		{
+		return ETrue;
+		}
+	CActiveScheduler* activeScheduler=CActiveScheduler::Current();
+	return (activeScheduler && activeScheduler->StackDepth()>0);
+	}
+
+TInt CVwsSessionWrapper::CheckCreateViewServerSession()
+// Possible return values:
+// KErrNone - connection suceeded.
+// KErrNotConnected- connection failed because server was not running.
+// KErrNoMemory - unable to allocate client side objects.
+	{
+	if (iVwsSession)
+		{
+		return KErrNone;
+		}
+
+	TRAPD(err,iVwsSession=new(ELeave) RVwsSession);
+	if(err!=KErrNone)
+		{
+		return err;
+		}
+
+	err=iVwsSession->Connect();
+	if (err==KErrNone)
+		{
+		if (iObserver) {
+			TInt priority=iVwsSession->GetPriority();
+			iViewEventHandler=new CVwsSessionEventHandler(*iObserver,*iVwsSession,priority);
+ 			if (iViewEventHandler==NULL)
+				{
+				iVwsSession->Close();
+				delete iVwsSession;
+				iVwsSession=NULL;
+				return KErrNoMemory;
+				}
+			}
+		return KErrNone;
+		}
+	else
+		{
+		delete iVwsSession;
+		iVwsSession=NULL;
+		if (err==KErrNotFound)
+			{	// It's not the view that's not found, but the server. Therefore switch to a more helpful error code.
+			return KErrCouldNotConnect;
+			}
+		else 
+			{
+			return err;
+			}
+		}
+	}
+
+
+//
+// Global functions.
+//
+
+GLDEF_C TInt ViewServerThreadStart(TAny* aPtr)
+	{
+	RThread thread;
+	TInt err=User::RenameThread(KVwsViewServerThreadName);
+	if (err!=KErrNone && err!=KErrAlreadyExists)
+		return err;
+	User::SetCritical(User::ESystemCritical);
+	thread.Close();
+
+	CActiveScheduler* scheduler=new CActiveScheduler;
+	if (!scheduler)
+		return KErrNoMemory;
+	CActiveScheduler::Install(scheduler);
+
+	CTrapCleanup* trapCleanup=CTrapCleanup::New();
+	if (!trapCleanup)
+		return KErrNoMemory;
+	SVwsCommandLine* comLine=STATIC_CAST(SVwsCommandLine*,aPtr);
+	CVwsServer* viewServer=NULL;
+	TRAP(err,viewServer=CVwsServer::NewL(*(comLine->iAppStarter)));
+	if (err!=KErrNone)
+		return err;
+	RThread::Rendezvous(KErrNone);
+
+	CActiveScheduler::Start();
+	delete viewServer;
+	delete CActiveScheduler::Current();
+	delete trapCleanup;
+	return KErrNone;
+	}
+
+GLREF_C void Panic(TVwsPanic aPanic)
+	{
+	_LIT(KViewServerPanic,"View Server client panic");
+	User::Panic(KViewServerPanic,aPanic);
+	}