appfw/viewserver/server/VWSEVENT.CPP
changeset 0 2e3d3ce01487
child 39 469fa8a78de7
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 // Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    17 #include "vwsinternal.h"
       
    18 #include "vwsdefpartner.h"
       
    19 #endif //SYMBIAN_ENABLE_SPLIT_HEADERS
       
    20 #include "VWSEVENT.H"
       
    21 #include "VWSERVER.H"
       
    22 #include "VWSDEBUG.H"
       
    23 #include "VWSPRIV.H"
       
    24 #include "vwspatchdata.h"
       
    25 
       
    26 #include <u32hal.h>
       
    27 
       
    28 
       
    29 
       
    30 //
       
    31 // class CVwsThreadWatcher
       
    32 //
       
    33 
       
    34 CVwsThreadWatcher::~CVwsThreadWatcher()
       
    35 	{
       
    36 	Cancel();
       
    37 	iThread.Close();
       
    38 	}
       
    39 
       
    40 CVwsThreadWatcher::CVwsThreadWatcher()
       
    41 	: CActive(EPriorityStandard)
       
    42 	{
       
    43 	}
       
    44 	
       
    45 TInt CVwsThreadWatcher::StartWatching(const TThreadId& aThreadId, const TCallBack& aCallBack)
       
    46 	{
       
    47 	iCallBack=aCallBack;
       
    48 	if(aThreadId!=iThread.Id())
       
    49 		{
       
    50 		if(IsAdded())
       
    51 			{
       
    52 			Deque();
       
    53 			iThread.Close();
       
    54 			}
       
    55 		TInt err=iThread.Open(aThreadId);
       
    56 		if (err==KErrNone)
       
    57 			{
       
    58 			CActiveScheduler::Add(this);
       
    59 			iThread.Logon(iStatus);
       
    60 			SetActive();
       
    61 			}
       
    62 		return err;
       
    63 		}
       
    64 	return KErrNone;
       
    65 	}
       
    66 
       
    67 void CVwsThreadWatcher::DoCancel()
       
    68 	{
       
    69 	iThread.LogonCancel(iStatus);
       
    70 	}
       
    71 
       
    72 void CVwsThreadWatcher::RunL()
       
    73 	{
       
    74 	iCallBack.CallBack();
       
    75 	}
       
    76 
       
    77 
       
    78 //
       
    79 // CVwsEventTimer.
       
    80 //
       
    81 
       
    82 CVwsEventTimer::~CVwsEventTimer()
       
    83 	{
       
    84 	delete iPeriodic;
       
    85 	}
       
    86 
       
    87 CVwsEventTimer* CVwsEventTimer::NewLC(const TTimeIntervalMicroSeconds32& aClientRequestTimeOut, const TTimeIntervalMicroSeconds32& aServerEventTimeOut)
       
    88 	{ // static
       
    89 	CVwsEventTimer* self = new(ELeave) CVwsEventTimer(aClientRequestTimeOut, aServerEventTimeOut);
       
    90 	CleanupStack::PushL(self);
       
    91 	self->ConstructL();
       
    92 	return self;
       
    93 	}
       
    94 
       
    95 CVwsEventTimer::CVwsEventTimer(const TTimeIntervalMicroSeconds32& aClientRequestTimeOut, const TTimeIntervalMicroSeconds32& aServerEventTimeOut)
       
    96 	: iClientRequestTimeOut(aClientRequestTimeOut),
       
    97 	  iServerEventTimeOut(aServerEventTimeOut),
       
    98 	  iTimeOutState(EUndefined),
       
    99 	  iScreenDeviceChangeEvent(EFalse)
       
   100 	{}
       
   101 
       
   102 void CVwsEventTimer::ConstructL()
       
   103 	{
       
   104 	iPeriodic=CPeriodic::NewL(0);
       
   105 	}
       
   106 
       
   107 void CVwsEventTimer::Start(MVwsEventTimerObserver* aObserver,const TBool& aScreenDeviceChangeEvent)
       
   108 	{
       
   109 	iObserver=aObserver;
       
   110 
       
   111 	if (iPeriodic->IsActive())
       
   112 		{
       
   113 		iPeriodic->Cancel();
       
   114 		}
       
   115 	
       
   116 	TTimeIntervalMicroSeconds32 firstDelay(0);
       
   117 	iTimeOutState=EUndefined;
       
   118 
       
   119 	if (iClientRequestTimeOut < iServerEventTimeOut)
       
   120 		{
       
   121 		iTimeOutState=EClientRequestTimeOut;
       
   122 		firstDelay=iClientRequestTimeOut;
       
   123 		}
       
   124 	else 
       
   125 		{
       
   126 		iTimeOutState=EServerEventTimeOut;
       
   127 		firstDelay=iServerEventTimeOut;
       
   128 		}
       
   129 
       
   130 	TTimeIntervalMicroSeconds32 delay(firstDelay);
       
   131 	iPeriodic->Start(delay,delay,TCallBack(TimerCallBack,this));	
       
   132 	iScreenDeviceChangeEvent = aScreenDeviceChangeEvent;
       
   133 
       
   134 	}
       
   135 
       
   136 TInt CVwsEventTimer::TimerCallBack(TAny* aSelf)
       
   137 	{ // static
       
   138 	REINTERPRET_CAST(CVwsEventTimer*,aSelf)->DoTimerCallBack();
       
   139 	return 0;
       
   140 	}
       
   141 
       
   142 void CVwsEventTimer::DoTimerCallBack()
       
   143 	{
       
   144 	if (iPeriodic != NULL && iPeriodic->IsActive())
       
   145 		{
       
   146 		iPeriodic->Cancel();
       
   147 		}
       
   148 	if (iScreenDeviceChangeEvent && iObserver)
       
   149 		{
       
   150 		iObserver->HandleTimeOut(iTimeOutState);
       
   151 		}
       
   152 	else
       
   153 		{
       
   154 		if (iObserver)
       
   155 			{
       
   156 			iObserver->HandleTimeOut(iTimeOutState);
       
   157 			}
       
   158 		if (iTimeOutState == EClientRequestTimeOut || iTimeOutState == EIntermediateEventTimeOut) 
       
   159 			{
       
   160 			TTimeIntervalMicroSeconds32 delay;
       
   161 			if (iTimeOutState == EClientRequestTimeOut) 
       
   162 				{
       
   163 				//Normal delay is given before considering boosting the priority of an application
       
   164 				delay = iServerEventTimeOut.Int()-iClientRequestTimeOut.Int();
       
   165 				iTimeOutState = EIntermediateEventTimeOut;
       
   166 				}
       
   167 			else
       
   168 				{
       
   169 				//Delay of KTimeoutValueForPreemptedProcess is given after boosting priority of an application
       
   170 				TUint8 patchableConst = KTimeoutValueForPreemptedProcess;
       
   171 				#ifdef __WINS__
       
   172 				// For the emulator allow the constant to be patched via epoc.ini
       
   173 				UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty,
       
   174 					(TAny*)"KTimeoutValueForPreemptedProcess", &patchableConst); // read emulator property (if present)
       
   175 				#endif
       
   176 				delay = patchableConst;
       
   177 				iTimeOutState = EServerEventTimeOut;
       
   178 				}
       
   179 			
       
   180             iPeriodic->Start(delay,delay,TCallBack(TimerCallBack,this));
       
   181 			}
       
   182 		}
       
   183 	}
       
   184 
       
   185 //
       
   186 // CVwsServerEvent.
       
   187 //
       
   188 
       
   189 CVwsServerEvent::CVwsServerEvent(CVwsServer& aServer,TType aType,CVwsEventQueue& aQueue)
       
   190 	:CVwsEvent(aType,aQueue),iServer(aServer)
       
   191 	{
       
   192 	}
       
   193 
       
   194 CVwsServerEvent::~CVwsServerEvent()
       
   195 	{
       
   196 	if (iObserved)
       
   197 		{
       
   198 		iObserved->NullifyObserver();
       
   199 		}
       
   200 	}
       
   201 
       
   202 
       
   203 void CVwsServerEvent::HandleLastOnQueue()
       
   204 	{
       
   205 	iServer.HandleLastServerEventOnQueue();
       
   206 	}
       
   207 
       
   208 
       
   209 //
       
   210 // CVwsServerEvent_Activate.
       
   211 //
       
   212 
       
   213 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)
       
   214 	: CVwsServerEvent(aServer,aType,aQueue),
       
   215 	iViewIdToActivate(aViewIdToActivate),
       
   216 	iClientMessage(aClientMessage),
       
   217 	iNewViewClientThreadId(0),
       
   218 	iCompleteRequest(aCompleteRequest),
       
   219 	iClientThreadId(aClientThreadId),
       
   220 	iMessage(aMessage),
       
   221 	iThreadWatcher(aThreadWatcher),
       
   222 	iEventTimer(aEventTimer),
       
   223 	iThreadOfClientInitiatingViewSwitch(aThreadOfClientInitiatingViewSwitch)
       
   224 	{
       
   225 	}
       
   226 
       
   227 CVwsServerEvent_Activate::~CVwsServerEvent_Activate()
       
   228 	{
       
   229 	delete iClientMessage;
       
   230 	delete iThreadWatcher;
       
   231 	delete iEventTimer;
       
   232 	iThreadOfClientInitiatingViewSwitch.Close();
       
   233 	}
       
   234 
       
   235 void CVwsServerEvent_Activate::HandleTimeOut(CVwsEventTimer::TTimeOut aTimeOut)
       
   236 	{
       
   237 	if (aTimeOut==CVwsEventTimer::EServerEventTimeOut && iServer.IsServerEventTimeOutEnabled())
       
   238 		{
       
   239 		if (iState==EActivationRequested)
       
   240 			{
       
   241 			LOG3(CVwsLog::ENormal,_L("PANIC CLIENT \"%x\" for timing out activation view event - activation request was not completed"),iViewIdToActivate.iAppUid.iUid);
       
   242 			if (TUint(iNewViewClientThreadId)!=0)
       
   243 				{
       
   244 				CVwsSession* newViewSession=iServer.SessionByThreadId(iNewViewClientThreadId);
       
   245 				if (newViewSession)
       
   246 					{
       
   247 					if (iServer.IsPriorityBoostBeforePanicEnabled())
       
   248 						{
       
   249 						if (iServer.InitializationFinished())
       
   250 							{
       
   251 							newViewSession->PanicClient(EVwsViewActivationEventTimeOut);
       
   252 							}
       
   253 						}
       
   254 					else
       
   255 						{
       
   256 						newViewSession->PanicClient(EVwsViewActivationEventTimeOut);
       
   257 						}
       
   258 					}
       
   259 				}
       
   260 			}
       
   261 		else if (iState==EDeactivationRequested)
       
   262 			{
       
   263 			LOG3(CVwsLog::ENormal,_L("PANIC CLIENT \"%x\" for timing out activation view event - deactivation request was not completed"),iServer.ActiveView().iAppUid.iUid);
       
   264 			CVwsSession* sessionWithActiveView=iServer.ActiveViewSession();
       
   265 			if (sessionWithActiveView)
       
   266 				{
       
   267 				if (iServer.IsPriorityBoostBeforePanicEnabled())
       
   268 					{
       
   269 					if (iServer.InitializationFinished())
       
   270 						{
       
   271 						sessionWithActiveView->PanicClient(EVwsViewDeactivationEventTimeOut);
       
   272 						}
       
   273 					}
       
   274 				else
       
   275 					{
       
   276 					sessionWithActiveView->PanicClient(EVwsViewDeactivationEventTimeOut);
       
   277 					}
       
   278 				}
       
   279 			}
       
   280 		else
       
   281 			{
       
   282 			LOG4(CVwsLog::EQuiet,_L("Aborting activation of view \"%x,%x\" - server event processing timed-out"),iViewIdToActivate.iAppUid.iUid,iViewIdToActivate.iViewUid.iUid);
       
   283 			Complete(KErrCancel);
       
   284 			}
       
   285 		}
       
   286 	else if (aTimeOut==CVwsEventTimer::EClientRequestTimeOut)
       
   287 			{
       
   288 			LOG2(CVwsLog::ELoud,_L("Activation event timer has passed client request time-out"));
       
   289 			if (iCompleteRequest==ECompleteRequest && iServer.SessionByThreadId(iClientThreadId)!=NULL)
       
   290 				{
       
   291 				LOG2(CVwsLog::ELoud,_L("Client request timed-out - silently completing request"));
       
   292 				iCompleteRequest=EDoNotCompleteRequest;
       
   293 				iMessage.Complete(KErrNone);
       
   294 				}
       
   295 			}
       
   296 		else if (aTimeOut==CVwsEventTimer::EIntermediateEventTimeOut) 
       
   297            { 
       
   298            if (iState==EActivationRequested) 
       
   299                { 
       
   300                iServer.BoostPriority(iServer.SessionByThreadId(iNewViewClientThreadId)); 
       
   301                } 
       
   302            else if (iState==EDeactivationRequested) 
       
   303                { 
       
   304                iServer.BoostPriority(iServer.ActiveViewSession()); 
       
   305                } 
       
   306            } 
       
   307 
       
   308 	}
       
   309 
       
   310 void CVwsServerEvent_Activate::ProcessEventL()
       
   311 	{
       
   312 LOG4(CVwsLog::ELoud,_L("Starting to process activation of \"%x,%x\""),iViewIdToActivate.iAppUid.iUid,iViewIdToActivate.iViewUid.iUid);
       
   313 
       
   314 	RequestActivateNewView();
       
   315 	}
       
   316 
       
   317 #ifdef _DEBUG
       
   318 void CVwsServerEvent_Activate::RequestCompleted(TRequestType aType,TInt aError,const RMessage2&)
       
   319 #else
       
   320 void CVwsServerEvent_Activate::RequestCompleted(TRequestType /*aType*/,TInt aError,const RMessage2&)
       
   321 #endif // _DEBUG
       
   322 	{
       
   323 	switch (iState)
       
   324 		{
       
   325 		case EPending:
       
   326 			ASSERT(EFalse);
       
   327 			break;
       
   328 		case EActivationRequested:
       
   329 			ASSERT(aType==MVwsSessionObserver::EActivation);
       
   330 			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);
       
   331 			if (aError)
       
   332 				{
       
   333 				if (aError==KErrViewWrongMode)
       
   334 					{
       
   335 					RequestActivateSystemDefaultView();
       
   336 					}
       
   337 				else
       
   338 					{
       
   339 					Complete(aError);
       
   340 					}
       
   341 				}
       
   342 			else
       
   343 				{
       
   344 				TVwsViewId viewToDeactivate(iServer.ActiveView());
       
   345 				// When an application whose view has to be activated is in background, the currently active view will not be deactivated.
       
   346 				// Note: Switching between different views of the same application must be followed by deactivation of old view
       
   347 				if ((iMessage.Int3() && !(iServer.IsAppInForeground())) && (viewToDeactivate.iAppUid != iViewIdToActivate.iAppUid))
       
   348 					{
       
   349 					LOG4(CVwsLog::ELoud,_L("\"%x,%x\", is activated at the background, so foreground view will not be deactivated"),iViewIdToActivate.iAppUid.iUid,iViewIdToActivate.iViewUid.iUid);
       
   350 					Complete(KErrNone);
       
   351 					}
       
   352 				else
       
   353 					{
       
   354 				RequestDeactivateOldView();
       
   355 					}
       
   356 				}
       
   357 			break;
       
   358 		case ESystemDefaultActivationRequested:
       
   359 			ASSERT(aType==MVwsSessionObserver::EActivation);
       
   360 			if (aError)
       
   361 				{
       
   362 				LOG3(CVwsLog::EQuiet,_L("Failed to activate system default view, error: %d"),aError);
       
   363 				RequestActivateSystemDefaultView();
       
   364 				}
       
   365 			else
       
   366 				{
       
   367 				RequestDeactivateOldView();
       
   368 				}
       
   369 			break;
       
   370 		case EDeactivationRequested:
       
   371 			ASSERT(aType==MVwsSessionObserver::EDeactivation);
       
   372 			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);
       
   373 			iServer.HandleDeactivation(iServer.ActiveView(),iViewIdToActivate);
       
   374 			Complete(KErrNone);
       
   375 			break;
       
   376 		default:
       
   377 		case EAppStartRequested:
       
   378 			ASSERT(EFalse);
       
   379 		}
       
   380 
       
   381 // Disable unused parameter warning under release builds
       
   382 #pragma warning (disable: 4100) 
       
   383 	}
       
   384 #pragma warning (default: 4100)
       
   385 
       
   386 void CVwsServerEvent_Activate::NowObserving(CVwsSessionEvent* aObserved)
       
   387 	{
       
   388 	if(iObserved)
       
   389 	    {
       
   390 	    iObserved->NullifyObserver();
       
   391 	    }
       
   392        	iObserved = aObserved;
       
   393 	}
       
   394 
       
   395 void CVwsServerEvent_Activate::NullifyObserved()
       
   396 	{
       
   397 	iObserved = NULL;	
       
   398 	}
       
   399 
       
   400 void CVwsServerEvent_Activate::HandleViewAdded(const TVwsViewId& aViewId, const TThreadId& aNewViewClientThreadId)
       
   401 	{
       
   402 	ASSERT(iState==EAppStartRequested);
       
   403 	if (aViewId.iAppUid==iViewIdToActivate.iAppUid
       
   404 	  &&aViewId.iAppUid==aViewId.iViewUid)
       
   405 		{
       
   406 		iViewIdToActivate = aViewId;
       
   407 		}
       
   408 	if (aViewId==iViewIdToActivate)
       
   409 		{
       
   410 		iServer.SetViewAdditionObserver(NULL);
       
   411 		
       
   412 		// set iNewViewClientThreadId to indicate that the new view should come from the session specified if possible
       
   413 		iNewViewClientThreadId = aNewViewClientThreadId;
       
   414 		RequestActivateNewView();
       
   415 		}
       
   416 	}
       
   417 
       
   418 void CVwsServerEvent_Activate::RequestActivateNewView()
       
   419 	{
       
   420 	CVwsSession* sessionWithNewView=iServer.SessionByThreadIdAndAppUid(iClientThreadId,iViewIdToActivate.iAppUid);
       
   421 	
       
   422 	// iNewViewClientThreadId may have been set by the caller to indicate a preference between
       
   423 	// sessions with the same App Uid
       
   424 	if (sessionWithNewView==NULL && iNewViewClientThreadId!=TThreadId(0))
       
   425 		{
       
   426 		sessionWithNewView=iServer.SessionByThreadIdAndAppUid(iNewViewClientThreadId,iViewIdToActivate.iAppUid);
       
   427 		}
       
   428 
       
   429 	if (sessionWithNewView==NULL)
       
   430 		{
       
   431 		sessionWithNewView=iServer.SessionByUid(iViewIdToActivate.iAppUid);
       
   432 		}
       
   433 
       
   434 	if (sessionWithNewView==NULL || (sessionWithNewView && sessionWithNewView->IsExiting()))
       
   435 		{
       
   436 		RequestAppStart();
       
   437 		}
       
   438 	else
       
   439 		{
       
   440 		iNewViewClientThreadId=sessionWithNewView->ClientThreadId();
       
   441 		DoRequestActivateNewView(*sessionWithNewView);
       
   442 		}
       
   443 	}
       
   444 
       
   445 void CVwsServerEvent_Activate::RequestActivateSystemDefaultView()
       
   446 	{
       
   447 	iServer.GetSystemDefaultView(iViewIdToActivate);
       
   448 	CVwsSession* sessionWithSystemDefaultView=iServer.SessionByUid(iViewIdToActivate.iAppUid);
       
   449 	// need an empty client message 
       
   450 	CVwsClientMessage* emptyClientMessage=CVwsClientMessage::New();
       
   451 	if (emptyClientMessage==NULL)
       
   452 		{
       
   453 		Complete(KErrNoMemory);
       
   454 		}
       
   455 
       
   456 	if (sessionWithSystemDefaultView)
       
   457 		{
       
   458 		iNewViewClientThreadId=sessionWithSystemDefaultView->ClientThreadId();
       
   459 		RequestClientActivation(*sessionWithSystemDefaultView,emptyClientMessage,ESystemDefaultActivationRequested);
       
   460 		}
       
   461 	else if (iThreadWatcher==NULL)
       
   462 		{
       
   463 		// app died
       
   464 		StopActivationProfile();
       
   465 		ASSERT(iState!=EAppStartRequested);	// Already asked to start app once.
       
   466 		StartAppStartProfile();
       
   467 		iServer.SetViewAdditionObserver(this);
       
   468 		TThreadId appThreadId;
       
   469 		iClientMessage = emptyClientMessage;
       
   470 		TInt err=iServer.StartApp(iViewIdToActivate.iAppUid,appThreadId);
       
   471 		if (err)
       
   472 			{
       
   473 			LOG3(CVwsLog::EQuiet,_L("App start FAILED with %d"),err);
       
   474 			Complete(err);
       
   475 			}
       
   476 		else
       
   477 			{
       
   478 			iState=EAppStartRequested;
       
   479 			}
       
   480 		}
       
   481 	else
       
   482 		{
       
   483 		delete emptyClientMessage;
       
   484 		}
       
   485 	}
       
   486 
       
   487 void CVwsServerEvent_Activate::RequestAppStart()
       
   488 	{
       
   489 	ASSERT(iState!=EAppStartRequested);	// Already asked to start app once.
       
   490 	StartAppStartProfile();
       
   491 	iServer.SetViewAdditionObserver(this);
       
   492 	TThreadId appThreadId;
       
   493 	TInt err=iServer.StartApp(iViewIdToActivate.iAppUid,appThreadId);
       
   494 	if (err)
       
   495 		{
       
   496 		LOG3(CVwsLog::EQuiet,_L("App start FAILED with %d"),err);
       
   497 		Complete(err);
       
   498 		}
       
   499 	else
       
   500 		{
       
   501 		iState=EAppStartRequested;
       
   502 		err=iThreadWatcher->StartWatching(appThreadId,TCallBack(&AppThreadWatcherCallBack,this));
       
   503 		if (err)
       
   504 			{
       
   505 			LOG3(CVwsLog::EQuiet,_L("App start FAILED with %d"),err);
       
   506 			Complete(err);
       
   507 			}
       
   508 		}
       
   509 	}
       
   510 
       
   511 TInt CVwsServerEvent_Activate::AppThreadWatcherCallBack(TAny* aPtr)
       
   512 	// static
       
   513 	{
       
   514 	LOG2(CVwsLog::EQuiet,_L("App start FAILED with app client thread death"));
       
   515 	REINTERPRET_CAST(CVwsServerEvent_Activate*,aPtr)->Complete(KErrCancel);
       
   516 	return 0;
       
   517 	}
       
   518 
       
   519 TInt CVwsServerEvent_Activate::RequestClientActivation(CVwsSession& aSession,CVwsClientMessage* aClientMessage,TState aNewState)
       
   520 	{
       
   521 	TRAPD(error,
       
   522 			aSession.RequestClientActivationL(*this,iViewIdToActivate,iServer.ActiveView(),aClientMessage,iThreadOfClientInitiatingViewSwitch));
       
   523 	if (error)
       
   524 		{
       
   525 		LOG3(CVwsLog::ELoud,_L("RequestClientActivationL FAILED with %d - unable to activate new view"),error);
       
   526 		if(aSession.IsLeaveAfterOwnershipTaken())
       
   527 			{
       
   528 			aSession.ResetLeaveAfterOwnershipTaken();
       
   529 			iClientMessage=NULL;
       
   530 			}
       
   531 		Complete(error);
       
   532 		}
       
   533 	else
       
   534 		{
       
   535 		iClientMessage=NULL; // The session is now the owner of the custom message buf.
       
   536 		iState=aNewState;
       
   537 		}
       
   538 	return error;
       
   539 	}
       
   540 
       
   541 void CVwsServerEvent_Activate::CustomCrossCheck(CVwsSession& aSessionWithNewView)
       
   542 	{
       
   543 	if (iClientMessage->iMessageId == KUidCustomCrossCheck && iClientMessage->iMessage == NULL)
       
   544 		{
       
   545 		iClientMessage->iMessageId = KNullUid;
       
   546 		TVwsViewId viewId;
       
   547 		if (aSessionWithNewView.GetTopView(viewId) == KErrNone)
       
   548 			{
       
   549 #ifdef _DEBUG
       
   550 			if (iViewIdToActivate != viewId)
       
   551 				{
       
   552 				LOG4(CVwsLog::ELoud,_L("Cross check to \"%x,%x\""), viewId.iAppUid.iUid, viewId.iViewUid.iUid);
       
   553 				}
       
   554 #endif //_DEBUG
       
   555 			iViewIdToActivate = viewId;
       
   556 			iClientMessage->iMessageId = KNullUid;
       
   557 			}
       
   558 		}
       
   559 	}
       
   560 
       
   561 void CVwsServerEvent_Activate::DoRequestActivateNewView(CVwsSession& aSessionWithNewView)
       
   562 	{
       
   563 	StopAppStartProfile();
       
   564 	delete iThreadWatcher;
       
   565 	iThreadWatcher=NULL;
       
   566 
       
   567 	iEventTimer->Start(this,EFalse);
       
   568 
       
   569 	if (iClientMessage)
       
   570 		{
       
   571 		CustomCrossCheck(aSessionWithNewView);
       
   572 		}
       
   573 
       
   574 	if (iServer.CheckViewExists(aSessionWithNewView.ClientThreadId(),iViewIdToActivate)==KErrNotFound)
       
   575 		{
       
   576 		LOG4(CVwsLog::EQuiet,_L("Aborting activation - view \"%x,%x\" not found"),iViewIdToActivate.iAppUid.iUid,iViewIdToActivate.iViewUid.iUid);
       
   577 		Complete(KErrNotFound);
       
   578 		return;
       
   579 		}
       
   580 
       
   581 	StartActivationProfile();
       
   582 	RequestClientActivation(aSessionWithNewView,iClientMessage,EActivationRequested);
       
   583 	}
       
   584 
       
   585 void CVwsServerEvent_Activate::RequestDeactivateOldView()
       
   586 	{
       
   587 	StopActivationProfile();
       
   588 	TVwsViewId viewToDeactivate(iServer.ActiveView());
       
   589 	CVwsSession* sessionWithOldView=iServer.ActiveViewSession();
       
   590 	CVwsSession* sessionWithNewView=iServer.SessionByThreadIdAndAppUid(iClientThreadId,iViewIdToActivate.iAppUid);
       
   591 		
       
   592 	//If the client that is requesting view activation is same as the client which has the new active view, ie, reactivation of same view, 
       
   593 	//then the session with new active view is taken. 
       
   594 	if (sessionWithNewView==NULL && iNewViewClientThreadId!=TThreadId(0))
       
   595 		{
       
   596 		sessionWithNewView=iServer.SessionByThreadIdAndAppUid(iNewViewClientThreadId,iViewIdToActivate.iAppUid);
       
   597 		}
       
   598 	
       
   599 	if (sessionWithNewView==NULL)
       
   600 		{
       
   601 		sessionWithNewView=iServer.SessionByUid(iViewIdToActivate.iAppUid);
       
   602 		}
       
   603 	
       
   604 	if (viewToDeactivate.iAppUid.iUid && (viewToDeactivate != iViewIdToActivate || sessionWithOldView != sessionWithNewView))
       
   605 		{
       
   606 		if (sessionWithOldView==NULL)
       
   607 			{	// Session with old view has disconnected, so abort deactivation.
       
   608 			LOG4(CVwsLog::ELoud,_L("Aborting deactivation of view \"%x,%x\" - client disconnected"),viewToDeactivate.iAppUid.iUid,viewToDeactivate.iViewUid.iUid);
       
   609 			Complete(KErrNone);
       
   610 			}
       
   611 		else
       
   612 			{
       
   613 			TBool differentInstanceOfSameApp = EFalse;
       
   614 			if (viewToDeactivate.iAppUid == iViewIdToActivate.iAppUid && sessionWithOldView != sessionWithNewView)
       
   615 				differentInstanceOfSameApp = ETrue;
       
   616 			TRAPD(err,sessionWithOldView->RequestClientDeactivationL(*this,viewToDeactivate,iViewIdToActivate, differentInstanceOfSameApp));
       
   617 			if (err)
       
   618 				{
       
   619 				LOG3(CVwsLog::ELoud,_L("RequestClientDeactivationL FAILED with %d - unable to deactivate currently active view"),err);
       
   620 				Complete(err);
       
   621 				}
       
   622 			else
       
   623 				{
       
   624 				iState=EDeactivationRequested;
       
   625 				}
       
   626 			}
       
   627 		}
       
   628 	else
       
   629 		{
       
   630 		// No view to deactivate, so complete.
       
   631 		LOG2(CVwsLog::ELoud,_L("Aborting deactivation - no view to deactivate"));
       
   632 		Complete(KErrNone);
       
   633 		}
       
   634 	}
       
   635 
       
   636 void CVwsServerEvent_Activate::Complete(TInt aError)
       
   637 	{
       
   638 	LOG5(CVwsLog::ELoud,_L("Completing activation of \"%x,%x\" with %d"),iViewIdToActivate.iAppUid,iViewIdToActivate.iViewUid,aError);
       
   639 	if (aError==KErrNone && TUint(iNewViewClientThreadId)!=0) 
       
   640 		{
       
   641 		iServer.HandleActivation(iViewIdToActivate,iServer.ActiveView());
       
   642 		TVwsViewId viewToDeactivate(iServer.ActiveView());
       
   643 		// The active active viewid will be set in the server when
       
   644 		// 1. Application whose view is getting activated is in foreground
       
   645 		// 2. Switching between different views of the same application
       
   646 		if(iServer.IsAppInForeground() || (iViewIdToActivate.iAppUid == viewToDeactivate.iAppUid))
       
   647 			{
       
   648 			iServer.SetActiveView(iNewViewClientThreadId,iViewIdToActivate);	
       
   649 			}
       
   650 		}
       
   651 	iServer.SetViewAdditionObserver(NULL);
       
   652 	if ((iCompleteRequest==ECompleteRequest) && (iServer.SessionByThreadId(iClientThreadId)!=NULL))
       
   653 		{
       
   654 		if(!iMessage.IsNull())
       
   655 			{
       
   656 			iMessage.Complete(aError);
       
   657 			}
       
   658 		}
       
   659 #ifdef __DO_LOGGING__
       
   660 	else if (iCompleteRequest==ECompleteRequest)
       
   661 		{
       
   662 		LOG2(CVwsLog::ELoud,_L("Client requesting activation not current - completing activation will not complete message handle"));
       
   663 		}
       
   664 #endif
       
   665 	ReportEventProcessed();
       
   666 	}
       
   667 
       
   668 void CVwsServerEvent_Activate::HandleSessionRemoval(const TThreadId& aClientThreadId)
       
   669 	{
       
   670 	TThreadId threadId(aClientThreadId);
       
   671 	TBool iCancel=EFalse;
       
   672 	if (iState==EDeactivationRequested)
       
   673 		{
       
   674 		CVwsSession* sessionWithActiveView=iServer.ActiveViewSession();
       
   675 		if (sessionWithActiveView && threadId==sessionWithActiveView->ClientThreadId())
       
   676 			{
       
   677 			LOG2(CVwsLog::ELoud,_L("Client with active view removed while session deactivation request outstanding"));
       
   678 			iCancel=ETrue;
       
   679 			}
       
   680 #ifdef __DO_LOGGING__
       
   681 		else if (threadId==iNewViewClientThreadId)
       
   682 			{
       
   683 			LOG2(CVwsLog::ELoud,_L("Client with new view removed while session deactivation request outstanding - waiting for deactivation to complete"));
       
   684 			}
       
   685 #endif
       
   686 		}
       
   687 	else if (threadId==iNewViewClientThreadId)
       
   688 		{
       
   689 		LOG2(CVwsLog::ELoud,_L("Client with new view removed"));
       
   690 		iCancel=ETrue;
       
   691 		}
       
   692 	if (iCancel)
       
   693 		{
       
   694 		LOG2(CVwsLog::ELoud,_L("Client removal means activation event will not complete normally - activation cancelled"));
       
   695 		Complete(KErrCancel);
       
   696 		}
       
   697 	}
       
   698 
       
   699 void CVwsServerEvent_Activate::StartAppStartProfile()
       
   700 	{
       
   701 	ASSERT(iWhichProfile==ENone);
       
   702 	iWhichProfile=EAppStart;
       
   703 	}
       
   704 
       
   705 void CVwsServerEvent_Activate::StopAppStartProfile()
       
   706 	{
       
   707 	if (iWhichProfile==EAppStart)
       
   708 		{
       
   709 		iWhichProfile=ENone;
       
   710 		}
       
   711 	}
       
   712 
       
   713 void CVwsServerEvent_Activate::StartActivationProfile()
       
   714 	{
       
   715 	ASSERT(iWhichProfile==ENone);
       
   716 	iWhichProfile=EActivation;
       
   717 	}
       
   718 
       
   719 void CVwsServerEvent_Activate::StopActivationProfile()
       
   720 	{
       
   721 	if (iWhichProfile==EActivation)
       
   722 		{
       
   723 		iWhichProfile=ENone;
       
   724 		}
       
   725 	}
       
   726 
       
   727 
       
   728 //
       
   729 // CVwsServerEvent_ScreenDeviceChanged.
       
   730 //
       
   731 
       
   732 CVwsServerEvent_ScreenDeviceChanged::CVwsServerEvent_ScreenDeviceChanged(CVwsServer& aServer,CVwsEventQueue& aQueue,CVwsThreadWatcher* aThreadWatcher,CVwsEventTimer* aEventTimer)
       
   733 	: CVwsServerEvent_Activate(aServer,CVwsServerEvent::ERejectPairs,aQueue,KNullViewId,NULL,RMessage2(),0,EDoNotCompleteRequest,aThreadWatcher,aEventTimer,RThread()),
       
   734 	iThreadWatcher(aThreadWatcher) ,iEventTimer(aEventTimer)
       
   735 	{
       
   736 	}
       
   737 
       
   738 CVwsServerEvent_ScreenDeviceChanged::~CVwsServerEvent_ScreenDeviceChanged()
       
   739 	{
       
   740 	}
       
   741 
       
   742 void CVwsServerEvent_ScreenDeviceChanged::ProcessEventL()
       
   743 	{
       
   744 	LOG2(CVwsLog::ELoud,_L("Started processing of screen device changed event"));
       
   745 	if(iServer.ActiveViewSession()!=NULL)
       
   746 		{
       
   747 		TThreadId activeClientThread = iServer.ActiveViewSession()->ClientThreadId();
       
   748 		TRAPD(err,iThreadWatcher->StartWatching(activeClientThread,TCallBack(&AppThreadWatcherCallBack,this)));
       
   749 		iEventTimer->Start(this,ETrue);
       
   750 		if (err)
       
   751 			{
       
   752 			Complete(err);
       
   753 			}
       
   754 		}
       
   755 	TVwsViewId activeView(iServer.ActiveView());
       
   756 	if (activeView.iAppUid.iUid)
       
   757 		{
       
   758 		RequestChangeNotification();
       
   759 		}
       
   760 	else
       
   761 		{
       
   762 		LOG2(CVwsLog::ELoud,_L("No active view, so ignoring screen device changed event"));
       
   763 		Complete(KErrNone);
       
   764 		}
       
   765 	}
       
   766 TInt CVwsServerEvent_ScreenDeviceChanged::AppThreadWatcherCallBack(TAny* aPtr)
       
   767 	// static
       
   768 	{
       
   769 	LOG2(CVwsLog::ELoud,_L("Client thread died while processing Screendevice change event"));
       
   770 	REINTERPRET_CAST(CVwsServerEvent_ScreenDeviceChanged*,aPtr)->Complete(KErrCancel);
       
   771 	return 0;
       
   772 	}
       
   773 
       
   774 void CVwsServerEvent_ScreenDeviceChanged::RequestCompleted(TRequestType aType,TInt aError,const RMessage2& aMessage)
       
   775 	{
       
   776 	switch (iScreenDeviceNotificationState)
       
   777 		{
       
   778 		case EPending:
       
   779 			ASSERT(EFalse);
       
   780 			break;
       
   781 		case EScreenDeviceChangeNotificationRequested:
       
   782 			{
       
   783 			ASSERT(aType==EScreenDeviceChangeNotification);
       
   784 			TRAPD(err,RequestActivationAsRequiredL(aMessage));
       
   785 			if (err)
       
   786 				{
       
   787 				LOG3(CVwsLog::ELoud,_L("CVwsClientMessage::NewL FAILED with %d, unable to activate view in responce to screen device changed event"),err);
       
   788 				RequestActivateSystemDefaultView();
       
   789 				}
       
   790 			}
       
   791 			break;
       
   792 		case EViewActivationRequested:
       
   793 		case EDefaultSystemViewActivationRequested:
       
   794 			CVwsServerEvent_Activate::RequestCompleted(aType,aError,aMessage);
       
   795 			break;
       
   796 		default:
       
   797 			ASSERT(EFalse);
       
   798 		}
       
   799 
       
   800 // Disable unused parameter warning under release builds
       
   801 #pragma warning (disable: 4100) 
       
   802 	}
       
   803 #pragma warning (default: 4100)
       
   804 
       
   805 void CVwsServerEvent_ScreenDeviceChanged::NowObserving(CVwsSessionEvent* aObserved)
       
   806 	{
       
   807 	if(iObserved)
       
   808 	    {
       
   809 	    iObserved->NullifyObserver();
       
   810 	    }
       
   811 	iObserved = aObserved;
       
   812 	}
       
   813 
       
   814 void CVwsServerEvent_ScreenDeviceChanged::NullifyObserved()
       
   815 	{
       
   816 	iObserved = NULL;	
       
   817 	}
       
   818 
       
   819 void CVwsServerEvent_ScreenDeviceChanged::RequestChangeNotification()
       
   820 	{
       
   821 	const TVwsViewId activeView(iServer.ActiveView());
       
   822 	CVwsSession* sessionWithActiveView=iServer.ActiveViewSession();
       
   823 	ASSERT(sessionWithActiveView); // Session with active view MUST be found.
       
   824 	TRAPD(err,sessionWithActiveView->RequestScreenDeviceChangeNotificationL(*this,activeView));
       
   825 	if (err)
       
   826 		{
       
   827 		LOG3(CVwsLog::ELoud,_L("RequestScreenDeviceChangeNotificationL FAILED with %d, unable to notify screen device changed"),err);
       
   828 		iScreenDeviceNotificationState=EDefaultSystemViewActivationRequested;
       
   829 		RequestActivateSystemDefaultView();
       
   830 		}
       
   831 	else
       
   832 		{
       
   833 		iScreenDeviceNotificationState=EScreenDeviceChangeNotificationRequested;
       
   834 		}
       
   835 	}
       
   836 
       
   837 void CVwsServerEvent_ScreenDeviceChanged::RequestActivationAsRequiredL(const RMessage2& aMessage)
       
   838 	{
       
   839 	TVwsViewIdAndMessageBuf viewToActivateBuf;
       
   840 	aMessage.ReadL(2,viewToActivateBuf);
       
   841 	TVwsViewIdAndMessage viewToActivate(viewToActivateBuf());
       
   842 	iViewIdToActivate=viewToActivate.iViewId;
       
   843 	if (iViewIdToActivate==TVwsViewId())
       
   844 		{	// Null view id, so ignore.
       
   845 		Complete(KErrNone);
       
   846 		}
       
   847 	else if (iServer.IsViewActive(iViewIdToActivate))
       
   848 		{
       
   849 		LOG4(CVwsLog::ELoud,_L("View \"%x,%x\" already active - aborting activation"),iViewIdToActivate.iAppUid.iUid,iViewIdToActivate.iViewUid.iUid);
       
   850 		Complete(KErrNone);
       
   851 		}
       
   852 	else
       
   853 		{
       
   854 		iClientMessage=CVwsClientMessage::NewL(viewToActivate.iCustomMessageId,viewToActivate.iCustomMessageLength,aMessage,3);
       
   855 		iScreenDeviceNotificationState=EViewActivationRequested;
       
   856 		
       
   857 		// Setting the iNewViewClientThreadId here indicates that if there are multiple sessions
       
   858 		// with the same app uid and we are switching views within one app then the one with the
       
   859 		// currently active view should be preferred
       
   860 		iNewViewClientThreadId = iServer.ActiveViewSession()->ClientThreadId();
       
   861 		RequestActivateNewView();
       
   862 		}
       
   863 	}
       
   864 
       
   865 #ifdef _DEBUG
       
   866 void CVwsServerEvent_ScreenDeviceChanged::Complete(TInt aError)
       
   867 #else
       
   868 void CVwsServerEvent_ScreenDeviceChanged::Complete(TInt /*aError*/)
       
   869 #endif // _DEBUG
       
   870 	{
       
   871 	LOG3(CVwsLog::ELoud,_L("Completed processing of screen device changed event with %d"),aError);
       
   872 	ReportEventProcessed();
       
   873 
       
   874 // Disable unused parameter warning under release builds
       
   875 #pragma warning (disable: 4100) 
       
   876 	}
       
   877 #pragma warning (default: 4100)
       
   878 
       
   879 void CVwsServerEvent_ScreenDeviceChanged::HandleAddedToQueue()
       
   880 	{
       
   881 	// display opaque intercepting window
       
   882 	iServer.MakeInterceptingWindowVisibleAndUpdateScreen();
       
   883 	}
       
   884 
       
   885 void CVwsServerEvent_ScreenDeviceChanged::HandleSessionRemoval(const TThreadId& aClientThreadId)
       
   886 	{
       
   887 	switch (iScreenDeviceNotificationState)
       
   888 		{
       
   889 	case EScreenDeviceChangeNotificationRequested:
       
   890 		{
       
   891 		CVwsSession* sessionWithActiveView=iServer.ActiveViewSession();
       
   892 		if(sessionWithActiveView && aClientThreadId==sessionWithActiveView->ClientThreadId())
       
   893 			{
       
   894 			LOG2(CVwsLog::ELoud,_L("Client with active view removed while screen device change request outstanding"));
       
   895 			RequestActivateSystemDefaultView();
       
   896 			iScreenDeviceNotificationState=EDefaultSystemViewActivationRequested;
       
   897 			}
       
   898 		}
       
   899 	case EViewActivationRequested:
       
   900 	case EDefaultSystemViewActivationRequested:
       
   901 		CVwsServerEvent_Activate::HandleSessionRemoval(aClientThreadId);
       
   902 		break;
       
   903 	case EPending:
       
   904 	default:
       
   905 		break;
       
   906 	}
       
   907 }
       
   908 
       
   909 void CVwsServerEvent_ScreenDeviceChanged::HandleTimeOut(CVwsEventTimer::TTimeOut /*aTimeOut*/)
       
   910 	{
       
   911 	LOG2(CVwsLog::ELoud,_L("CVwsServerEvent_ScreenDeviceChanged view event timer has passed client request time-out"));
       
   912 	switch (iScreenDeviceNotificationState)
       
   913 		{
       
   914 		case EScreenDeviceChangeNotificationRequested:
       
   915 			Complete(KErrNone);
       
   916 			break;
       
   917 
       
   918 		case EViewActivationRequested:
       
   919 		case EDefaultSystemViewActivationRequested:
       
   920 			CVwsServerEvent_Activate::HandleTimeOut(CVwsEventTimer::EClientRequestTimeOut);
       
   921 			break;
       
   922 
       
   923 		case EPending:
       
   924 		default:
       
   925 			break;
       
   926 		}
       
   927 	}
       
   928 
       
   929 //
       
   930 // CVwsServerEvent_DeactivateActiveView.
       
   931 //
       
   932 
       
   933 CVwsServerEvent_DeactivateActiveView::CVwsServerEvent_DeactivateActiveView(CVwsServer& aServer,CVwsEventQueue& aQueue,const RMessage2& aMessage,const TThreadId& aClientThreadId,TVwsCompleteRequest aCompleteRequest,CVwsEventTimer* aEventTimer)
       
   934 	: CVwsServerEvent(aServer,CVwsServerEvent::ENormal,aQueue),
       
   935 	iMessage(aMessage),
       
   936 	iClientThreadId(aClientThreadId),
       
   937 	iCompleteRequest(aCompleteRequest),
       
   938 	iEventTimer(aEventTimer)
       
   939 	{
       
   940 	}
       
   941 
       
   942 CVwsServerEvent_DeactivateActiveView::~CVwsServerEvent_DeactivateActiveView()
       
   943 	{
       
   944 	delete iEventTimer;
       
   945 	}
       
   946 
       
   947 void CVwsServerEvent_DeactivateActiveView::ProcessEventL()
       
   948 	{
       
   949 	LOG2(CVwsLog::ELoud,_L("Started processing of deactivate active view event"));
       
   950 	const TVwsViewId activeView(iServer.ActiveView());
       
   951 
       
   952 	//Check if the Cross Check UID is set, if it is then enable customised behaviour here
       
   953 	if(iServer.CrossCheckUid()!=KNullUid)
       
   954 		{
       
   955 		CVwsSession* self = iServer.SessionByThreadId(iClientThreadId);
       
   956 		CVwsSession* active = iServer.ActiveViewSession();
       
   957 		if (self != active)
       
   958 			{
       
   959 			LOG2(CVwsLog::ELoud,_L("Requested session does not have Active view, so ignoring deactivate active view event"));
       
   960 			if(iCompleteRequest==ECompleteRequest&& iServer.SessionByThreadId(iClientThreadId)!=NULL)
       
   961 				{
       
   962 				iMessage.Complete(KErrNone);
       
   963 				}
       
   964 			ReportEventProcessed();
       
   965 			return;
       
   966 			}
       
   967 		}
       
   968 
       
   969 	if (activeView.iAppUid.iUid)
       
   970 		{
       
   971 		TRAPD(err,RequestDeactivationL());
       
   972 		if (err)
       
   973 			{
       
   974 			Complete(err);
       
   975 			}
       
   976 		}
       
   977 	else
       
   978 		{
       
   979 		LOG2(CVwsLog::ELoud,_L("No active view, so ignoring deactivate active view event"));
       
   980 		Complete(KErrNone);
       
   981 		}
       
   982 	}
       
   983 
       
   984 #ifdef _DEBUG
       
   985 void CVwsServerEvent_DeactivateActiveView::RequestCompleted(TRequestType aType,TInt,const RMessage2&)
       
   986 #else
       
   987 void CVwsServerEvent_DeactivateActiveView::RequestCompleted(TRequestType /*aType*/,TInt,const RMessage2&)
       
   988 #endif // _DEBUG
       
   989 	{
       
   990 	switch (iState)
       
   991 		{
       
   992 		case EPending:
       
   993 			ASSERT(EFalse);
       
   994 			break;
       
   995 		case EDeactivationRequested:
       
   996 			ASSERT(aType==EDeactivation);
       
   997 			Complete(KErrNone);
       
   998 			break;
       
   999 		default:
       
  1000 			ASSERT(EFalse);
       
  1001 		}
       
  1002 
       
  1003 // Disable unused parameter warning under release builds
       
  1004 #pragma warning (disable: 4100) 
       
  1005 	}
       
  1006 #pragma warning (default: 4100)
       
  1007 
       
  1008 void CVwsServerEvent_DeactivateActiveView::NowObserving(CVwsSessionEvent* aObserved)
       
  1009 	{
       
  1010 	if(iObserved)
       
  1011 	    {
       
  1012 	    iObserved->NullifyObserver();
       
  1013 	    }
       
  1014 	iObserved = aObserved;
       
  1015 	}
       
  1016 
       
  1017 void CVwsServerEvent_DeactivateActiveView::NullifyObserved()
       
  1018 	{
       
  1019 	iObserved = NULL;	
       
  1020 	}
       
  1021 
       
  1022 void CVwsServerEvent_DeactivateActiveView::RequestDeactivationL()
       
  1023 	{
       
  1024 	ASSERT(iState==EPending);
       
  1025 
       
  1026 	iEventTimer->Start(this,EFalse);
       
  1027 
       
  1028 	iActiveView=iServer.ActiveView();
       
  1029 	CVwsSession* sessionWithActiveView=iServer.ActiveViewSession();
       
  1030 	// If the session with currently active view is NULL, then the deactivation request is
       
  1031  	// completed with KErrNotFound and the previously active view is activated.
       
  1032 	if (sessionWithActiveView)
       
  1033  		{
       
  1034  		//EFalse always because the deactivation of view is requested by the application directly
       
  1035  		sessionWithActiveView->RequestClientDeactivationL(*this,iActiveView,TVwsViewId(),EFalse);
       
  1036  		iState=EDeactivationRequested;
       
  1037  		}
       
  1038  	else
       
  1039  		{
       
  1040  		LOG2(CVwsLog::ELoud,_L("Session with active view is NULL, so completing the deactivation request with KErrNotFound"));
       
  1041  		User::Leave(KErrNotFound);
       
  1042  		}
       
  1043 	}
       
  1044 
       
  1045 void CVwsServerEvent_DeactivateActiveView::Complete(TInt aErr)
       
  1046 	{
       
  1047 	LOG3(CVwsLog::ELoud,_L("Completing deactivate active view event with %d"),aErr);
       
  1048 	if (aErr)
       
  1049 		{
       
  1050 		iServer.HandleDeactivation(iActiveView,TVwsViewId());
       
  1051 		}
       
  1052 	iServer.ClearActiveView();
       
  1053 	if(iCompleteRequest==ECompleteRequest&& iServer.SessionByThreadId(iClientThreadId)!=NULL)
       
  1054 		{
       
  1055 		iMessage.Complete(aErr);
       
  1056 		}
       
  1057 	ReportEventProcessed();
       
  1058 	}
       
  1059 
       
  1060 void CVwsServerEvent_DeactivateActiveView::HandleSessionRemoval(const TThreadId& aClientThreadId)
       
  1061 	{
       
  1062 	TThreadId threadId(aClientThreadId);
       
  1063 	if (iState==EDeactivationRequested)
       
  1064 		{
       
  1065 		CVwsSession* sessionWithActiveView=iServer.ActiveViewSession();
       
  1066 		if (sessionWithActiveView && threadId==sessionWithActiveView->ClientThreadId())
       
  1067 			{
       
  1068 			LOG2(CVwsLog::ELoud,_L("Client with active view removed while session deactivation request outstanding"));
       
  1069 			LOG2(CVwsLog::ELoud,_L("Client removal means deactivate active view event will not complete normally - deactivation cancelled"));
       
  1070 			Complete(KErrCancel);
       
  1071 			}
       
  1072 		}
       
  1073 	}
       
  1074 
       
  1075 void CVwsServerEvent_DeactivateActiveView::HandleTimeOut(CVwsEventTimer::TTimeOut aTimeOut)
       
  1076 	{
       
  1077 	if (aTimeOut==CVwsEventTimer::EServerEventTimeOut && iServer.IsServerEventTimeOutEnabled())
       
  1078 		{
       
  1079 		if (iState==EDeactivationRequested)
       
  1080 			{
       
  1081 			LOG3(CVwsLog::ENormal,_L("PANIC CLIENT \"%x\" for timing out activation view event - deactivation request was not completed"),iServer.ActiveView().iAppUid.iUid);
       
  1082 			CVwsSession* sessionWithActiveView=iServer.ActiveViewSession();
       
  1083 			if (sessionWithActiveView)
       
  1084 				{
       
  1085 				if(iServer.IsPriorityBoostBeforePanicEnabled())
       
  1086 					{
       
  1087 					if (iServer.InitializationFinished())
       
  1088 						{
       
  1089 						sessionWithActiveView->PanicClient(EVwsViewDeactivationEventTimeOut);
       
  1090 						}
       
  1091 					}
       
  1092 				else
       
  1093 					{
       
  1094 					sessionWithActiveView->PanicClient(EVwsViewDeactivationEventTimeOut);
       
  1095 					}
       
  1096 				}
       
  1097 			}
       
  1098 		else
       
  1099 			{
       
  1100 			LOG4(CVwsLog::EQuiet,_L("Aborting deactivation of active view \"%x,%x\" - server event processing timed-out"),iServer.ActiveView().iAppUid.iUid,iServer.ActiveView().iViewUid.iUid);
       
  1101 			Complete(KErrCancel);
       
  1102 			}
       
  1103 		}
       
  1104 	else if (aTimeOut==CVwsEventTimer::EClientRequestTimeOut)
       
  1105 			{
       
  1106 			LOG2(CVwsLog::ELoud,_L("Deactivate active view event timer has passed client request time-out"));
       
  1107 			if (iCompleteRequest==ECompleteRequest && iServer.SessionByThreadId(iClientThreadId)!=NULL)
       
  1108 				{
       
  1109 				LOG2(CVwsLog::ELoud,_L("Client request timed-out - silently completing request"));
       
  1110 				iCompleteRequest=EDoNotCompleteRequest;
       
  1111 				iMessage.Complete(KErrNone);
       
  1112 				}
       
  1113 			}
       
  1114 		else if (aTimeOut==CVwsEventTimer::EIntermediateEventTimeOut) 
       
  1115            { 
       
  1116            if (iState==EDeactivationRequested) 
       
  1117                { 
       
  1118                iServer.BoostPriority(iServer.ActiveViewSession()); 
       
  1119                } 
       
  1120            }
       
  1121 	}
       
  1122 
       
  1123 //
       
  1124 // CVwsServerEvent_AppStart.
       
  1125 //
       
  1126 
       
  1127 CVwsServerEvent_AppStart::CVwsServerEvent_AppStart(CVwsServer& aServer,CVwsEventQueue& aQueue,const RMessage2& aMessage,const TUid& aAppToStart,CVwsThreadWatcher* aThreadWatcher)
       
  1128 	: CVwsServerEvent(aServer,CVwsServerEvent::ENormal,aQueue),iAppToStart(aAppToStart),iMessage(aMessage),iThreadWatcher(aThreadWatcher)
       
  1129 	{
       
  1130 	}
       
  1131 
       
  1132 CVwsServerEvent_AppStart::~CVwsServerEvent_AppStart()
       
  1133 	{
       
  1134 	delete iThreadWatcher;
       
  1135 	}
       
  1136 
       
  1137 void CVwsServerEvent_AppStart::ProcessEventL()
       
  1138 	{
       
  1139 	LOG2(CVwsLog::ELoud,_L("Started processing of app start event"));
       
  1140 
       
  1141 	iSessionWithNewApp=iServer.SessionByUid(iAppToStart);
       
  1142 	if (iSessionWithNewApp==NULL)
       
  1143 		{
       
  1144 		RequestAppStart();
       
  1145 		}
       
  1146 	else
       
  1147 		{
       
  1148 		Complete(KErrNone);
       
  1149 		}
       
  1150 	}
       
  1151 
       
  1152 void CVwsServerEvent_AppStart::HandleViewAdded(const TVwsViewId& aViewId, const TThreadId& aNewViewClientThreadId)
       
  1153 	{
       
  1154 	ASSERT(iState==EAppStartRequested);
       
  1155 
       
  1156 	if (aViewId.iAppUid==iAppToStart)
       
  1157 		{
       
  1158 		delete iThreadWatcher;
       
  1159 		iThreadWatcher=NULL;
       
  1160 		iServer.SetViewAdditionObserver(NULL);
       
  1161 		ASSERT(iSessionWithNewApp==NULL);
       
  1162 		iSessionWithNewApp=iServer.SessionByThreadIdAndAppUid(aNewViewClientThreadId,aViewId.iAppUid);
       
  1163 		ASSERT(iSessionWithNewApp);
       
  1164 		Complete(KErrNone);
       
  1165 		}
       
  1166 	}
       
  1167 
       
  1168 void CVwsServerEvent_AppStart::RequestAppStart()
       
  1169 	{
       
  1170 	iServer.SetViewAdditionObserver(this);
       
  1171 	TThreadId appThreadId;
       
  1172 	TInt err=iServer.StartApp(iAppToStart,appThreadId);
       
  1173 	if (err)
       
  1174 		{
       
  1175 		LOG3(CVwsLog::EQuiet,_L("App start FAILED with %d"),err);
       
  1176 		Complete(err);
       
  1177 		}
       
  1178 	else
       
  1179 		{
       
  1180 		iState=EAppStartRequested;
       
  1181 		err=iThreadWatcher->StartWatching(appThreadId,TCallBack(&AppThreadWatcherCallBack,this));
       
  1182 		if (err)
       
  1183 			{
       
  1184 			LOG3(CVwsLog::EQuiet,_L("App start FAILED with %d"),err);
       
  1185 			Complete(err);
       
  1186 			}
       
  1187 		}
       
  1188 	}
       
  1189 
       
  1190 TInt CVwsServerEvent_AppStart::AppThreadWatcherCallBack(TAny* aPtr)
       
  1191 	// static
       
  1192 	{
       
  1193 	LOG2(CVwsLog::EQuiet,_L("App start FAILED with app client thread death"));
       
  1194 	REINTERPRET_CAST(CVwsServerEvent_AppStart*,aPtr)->Complete(KErrCancel);
       
  1195 	return 0;
       
  1196 	}
       
  1197 
       
  1198 void CVwsServerEvent_AppStart::Complete(TInt aErr)
       
  1199 	{
       
  1200 	LOG3(CVwsLog::EQuiet,_L("App start event completed with %d"),aErr);
       
  1201 	iServer.SetViewAdditionObserver(NULL);
       
  1202 	iMessage.Complete(aErr);
       
  1203 	ReportEventProcessed();
       
  1204 	}