diff -r 000000000000 -r 2e3d3ce01487 appfw/viewserver/server/VWSERVER.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/appfw/viewserver/server/VWSERVER.CPP Tue Feb 02 10:12:00 2010 +0200 @@ -0,0 +1,856 @@ +// 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 +#include + +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include "vwsinternal.h" +#include "vwsdefpartner.h" +#endif //SYMBIAN_ENABLE_SPLIT_HEADERS + +#include "VWSERVER.H" +#include "VWSSESSN.H" +#include "VWSEVENT.H" +#include "VWSWEVNT.H" +#include "VWSADDOB.H" +#include "VWSPRIV.H" +#include "VWSDEBUG.H" +#include "vwspatchdata.h" + + +#include +#include +#include +#include + +// +// Constants. +// + +const TInt KVwsSystemDefaultViewArrayGranularity=2; +const TInt KDefaultClientRequestTimeOutDuration=1000000; +const TInt KDefaultServerEventTimeOutDuration=10000000; + +_LIT(KPriorityFilename,"Z:\\resource\\apps\\PrioritySet.rsc"); + + +const TUint8 KPolicyElementSID = 0; +const TUint8 KPolicyPowerMgmt = 1; + +const TInt KEiksrvsSid=0x10003a4a; + +const TUint KRangeCount = 5; + +const TInt KVwsServerRanges[KRangeCount] = + { + EFirstUnrestrictedOpcodeInVws, + EFirstOpcodeNeedingCustomCheckInVws, + EFirstOpcodeNeedingSecureIdInVws, + EFirstOpCodeNeedingPowerMgmt, + EVwsFirstUnusedOpcode, + }; + +const TUint8 KElementsIndex[KRangeCount] = + { + CPolicyServer::EAlwaysPass, //Always passing no capability required [EFirstUnrestrictedOpcodeInVws-(EFirstOpcodeNeedingCustomCheckInVws-1)] + CPolicyServer::ECustomCheck, //Requires Custom check [EFirstOpcodeNeedingCustomCheckInVws-(EFirstOpcodeNeedingSecureIdInVws-1)] + KPolicyElementSID, //Requires SID to be of Eiksrvs ie.0x10003a4a [EFirstOpcodeNeedingSecureIdInVws-(EFirstOpCodeNeedingPowerMgmt-1)] + KPolicyPowerMgmt, //Requires PowerMgmt capability [EFirstOpCodeNeedingPowerMgmt-(EVwsFirstUnusedOpcode-1)] + CPolicyServer::ENotSupported, //Not Supported + }; + +const CPolicyServer::TPolicyElement KPolicyElements[] = + { + {_INIT_SECURITY_POLICY_S0(KEiksrvsSid), CPolicyServer::EFailClient}, + {_INIT_SECURITY_POLICY_C1(ECapabilityPowerMgmt), CPolicyServer::EFailClient} + }; + +const CPolicyServer::TPolicy KVwsServerPolicy = + { + CPolicyServer::EAlwaysPass, + KRangeCount, + KVwsServerRanges, + KElementsIndex, + KPolicyElements + }; + +// +// CVwsServer. +// + +#ifdef __DO_LOGGING__ +CVwsServer::CVwsServer(TInt aPriority,MVwsAppStarter& aAppStarter) + : CPolicyServer(aPriority,KVwsServerPolicy), + iAppStarter(aAppStarter), + iSystemDefaultViewIdArray(KVwsSystemDefaultViewArrayGranularity), + iClientRequestTimeOut(KDefaultClientRequestTimeOutDuration), + iServerEventTimeOut(KDefaultServerEventTimeOutDuration), + iForegroundChangeWhileEventsOutstanding(EFalse), + iIsServerEventTimeOutDisabled(0), + iNoActivationRequests(0), + iEnableServerBlankScreen(ETrue), + iEnableBoostAppPriorityBeforePanic(KVwsBoostAppPriorityBeforePanic) + { + } +#else +CVwsServer::CVwsServer(TInt aPriority,MVwsAppStarter& aAppStarter) + : CPolicyServer(aPriority,KVwsServerPolicy), + iAppStarter(aAppStarter), + iSystemDefaultViewIdArray(KVwsSystemDefaultViewArrayGranularity), + iClientRequestTimeOut(KDefaultClientRequestTimeOutDuration), + iServerEventTimeOut(KDefaultServerEventTimeOutDuration), + iForegroundChangeWhileEventsOutstanding(EFalse), + iIsServerEventTimeOutDisabled(0), + iEnableServerBlankScreen(ETrue), + iEnableBoostAppPriorityBeforePanic(KVwsBoostAppPriorityBeforePanic) + { + } +#endif + +EXPORT_C CVwsServer* CVwsServer::NewL(MVwsAppStarter& aAppStarter) + { + CVwsServer *pS=new CVwsServer(CActive::EPriorityStandard,aAppStarter); + __ASSERT_ALWAYS(pS!=NULL,PanicServer(EVwsServerCreate)); + + pS->ConstructL(); + + pS->StartL(KViewServerName); + return pS; + } + +CSession2* CVwsServer::NewSessionL(const TVersion &aVersion,const RMessage2& aMessage) const + { + // Check version supported. + TVersion version(KVwsMajorVersionNumber,KVwsMinorVersionNumber,KVwsBuildVersionNumber); + if (!User::QueryVersionSupported(version,aVersion)) + { + User::Leave(KErrNotSupported); + } + + RThread thread; + User::LeaveIfError(aMessage.Client(thread)); + const TThreadId threadId(thread.Id()); + thread.Close(); + return CVwsSession::NewL(threadId,CONST_CAST(CVwsServer&,*this)); + } + + +EXPORT_C CVwsServer::~CVwsServer() + { + delete iWServSessionHandler; + + delete iEventQueue; +#ifdef __DO_LOGGING__ + CVwsLog::ShutdownLog(); +#endif + } + +void CVwsServer::ConstructL() + { + // required for handling intercepting window + iWServSessionHandler=CVwsWServSessionHandler::NewL(*this); + +#ifdef __DO_LOGGING__ + iEventQueue=new(ELeave) CVwsEventQueue(_L("Server Queue")); + CVwsLog::StartLogL(); +#else + iEventQueue=new(ELeave) CVwsEventQueue; +#endif + RFs fs; + iPrioritySet=CActive::EPriorityStandard; + CleanupClosePushL(fs); + if(fs.Connect()==KErrNone) + { + CResourceFile* file=NULL; + TRAPD(err, file=CResourceFile::NewL(fs, KPriorityFilename, 0, 0)); + if(err == KErrNone) + { + CleanupStack::PushL(file); + RResourceReader reader; + reader.OpenL(file, 2); + CleanupClosePushL(reader); + iPrioritySet=reader.ReadUint32L(); + CleanupStack::PopAndDestroy(&reader); + CleanupStack::PopAndDestroy(file); + } + fs.Close(); + } + + CleanupStack::PopAndDestroy(&fs); + + + + + +#ifdef __WINS__ + // KVwsBoostAppPriorityBeforePanic is a Rom patchable constant, so need an emulator equivalent + // if WINS then read value from epoc.ini requires licencees to set property in epoc.ini. + // Usage: In epoc.ini patchdata_viewsrv_dll_KVwsBoostAppPriorityBeforePanic 1 + + TInt valueOfKVwsBoostAppPriorityBeforePanic = 0; + if (UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"patchdata_viesrv_dll_KVwsBoostAppPriorityBeforePanic",&valueOfKVwsBoostAppPriorityBeforePanic) == KErrNone) + { + iEnableBoostAppPriorityBeforePanic = valueOfKVwsBoostAppPriorityBeforePanic; + } +#endif + + if (iEnableBoostAppPriorityBeforePanic) + { + CVwsStartupAware* startupAware = new(ELeave)CVwsStartupAware(*this); + TInt err = startupAware->Start(); + if (err != KErrNone) + { + HandleInitializationFinished(); + delete startupAware; + } + } + } + +CVwsStartupAware::CVwsStartupAware(CVwsServer& aServer) + :CActive(CActive::EPriorityStandard),iServer(aServer) + { + CActiveScheduler::Add(this); + } + +CVwsStartupAware::~CVwsStartupAware() + { + Cancel(); + iStateAwareSession.Close(); + } + +TInt CVwsStartupAware::Start() + { + TInt err = iStateAwareSession.Connect(KSM2UiServicesDomain3); + if(iStateAwareSession.State().MainState() != ESsmNormal && err == KErrNone) + { + iStateAwareSession.RequestStateNotification(iStatus); + SetActive(); + } + return err; + } + +void CVwsStartupAware::RunL() + { + if (iStatus == KErrNone) + { + if (iStateAwareSession.State().MainState() == ESsmNormal) + { + iServer.HandleInitializationFinished(); //Bootup is complete now, allowing Viewsrv 11 panics to occur here onwards + delete this; + } + else + { + iStateAwareSession.AcknowledgeAndRequestStateNotification(KErrNone, iStatus); + SetActive(); + } + } + } + +void CVwsStartupAware::DoCancel() + { + iStateAwareSession.RequestStateNotificationCancel(); + } + +void CVwsServer::PanicClient(TInt aPanic) const + { + _LIT(KVwsSrvPanic, "ViewSrv"); + User::Panic(KVwsSrvPanic,aPanic); + } + +void CVwsServer::SetSystemDefaultViewL(TInt aMode,const TVwsViewId& aViewId) + { + __ASSERT_DEBUG(aMode>=0,PanicClient(EVwsInvalidScreenMode)); + const TInt count = iSystemDefaultViewIdArray.Count(); + + if ((aMode>count) || (aMode<0)) + { + PanicClient(EVwsInvalidScreenMode); + } + else if (aMode < count) + { + iSystemDefaultViewIdArray.At(aMode) = aViewId; + } + else if (aMode == count) + { + iSystemDefaultViewIdArray.AppendL(aViewId); + } + } + +void CVwsServer::SetClientRequestTimeOut(const TTimeIntervalMicroSeconds32& aDuration) + { + iClientRequestTimeOut=aDuration; + } + +void CVwsServer::SetServerEventTimeOut(const TTimeIntervalMicroSeconds32& aDuration) + { + iServerEventTimeOut=aDuration; + } + +void CVwsServer::EnableServerEventTimeOut(TBool aEnable) + { + if (!aEnable) + { + iIsServerEventTimeOutDisabled++; + } + else if (iIsServerEventTimeOutDisabled) + { + iIsServerEventTimeOutDisabled--; + } + } + +void CVwsServer::EnableServerBlankScreen(TBool aEnable) + { + iEnableServerBlankScreen = aEnable; + } + +void CVwsServer::GetSystemDefaultView(TVwsViewId& aViewId) + { + TInt mode=iWServSessionHandler->GetScreenMode(); + aViewId = (mode>=0 && modeGetScreenMode(); + } + +TBool CVwsServer::IsSystemDefaultView(const TVwsViewId& aViewId) + { + TBool ret=EFalse; + + const TInt numViews=iSystemDefaultViewIdArray.Count(); + for (TInt ii=0;iiProcessEventL(activationEvent); +#ifdef __DO_LOGGING__ + iNoActivationRequests++; + LOG3(CVwsLog::ELoud,_L("Cumulative activation requests since server start - %d"),iNoActivationRequests); +#endif + } + +void CVwsServer::ActivateViewL(const TVwsViewId& aViewId,CVwsClientMessage* aClientMessage,const RMessage2& aMessage,const CVwsSession& aSession,TVwsCompleteRequest aCompleteRequest) + { + ActivateViewL(aViewId,aClientMessage,aMessage,aSession.ClientThreadId(),aCompleteRequest); + } + +TVwsViewId CVwsServer::ActiveView() + { + for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) + { + CSession2* baseSession=iSessionIter; + CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); + + if (thisSession->HasActiveView()) + { + return thisSession->ActiveView(); + } + } + + return KNullViewId; + } + +void CVwsServer::SetActiveView(const TThreadId& aThreadId,const TVwsViewId& aViewId) + { +#ifdef _DEBUG + TVwsViewId activeView=ActiveView(); + + if (activeView != KNullViewId) + { + LOG6(CVwsLog::EQuiet,_L("Changing active view to \"%x,%x\" [previously \"%x,%x\"]"),aViewId.iAppUid.iUid,aViewId.iViewUid.iUid,activeView.iAppUid.iUid,activeView.iViewUid.iUid); + } + else + { + LOG4(CVwsLog::EQuiet,_L("Changing active view to \"%x,%x\" [no view previously active]"),aViewId.iAppUid.iUid,aViewId.iViewUid.iUid); + } +#endif + + for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) + { + CSession2* baseSession=iSessionIter; + CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); + + if (thisSession->ClientThreadId()==aThreadId) + { + thisSession->SetActiveView(aViewId); + } + else if (thisSession->HasActiveView()) + { + thisSession->ClearActiveView(); + } + } + } + +void CVwsServer::ClearActiveView() + { + for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) + { + CSession2* baseSession=iSessionIter; + CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); + + if (thisSession->HasActiveView()) + { + thisSession->ClearActiveView(); + break; + } + } + } + +void CVwsServer::SetViewAdditionObserver(MVwsViewAdditionObserver* aViewAdditionObserver) + { + ASSERT((iViewAdditionObserver==NULL) || (aViewAdditionObserver==NULL)); + iViewAdditionObserver=aViewAdditionObserver; + } + +void CVwsServer::HandleScreenDeviceChangedL() + { + LOG2(CVwsLog::ENormal,_L("Received screen device changed notification from WServ, creating event to handle it")); + CVwsThreadWatcher* threadWatcher=new(ELeave) CVwsThreadWatcher(); + CleanupStack::PushL(threadWatcher); + CVwsEventTimer* eventTimer=CVwsEventTimer::NewLC(iClientRequestTimeOut,iServerEventTimeOut); + CVwsServerEvent* screenDeviceChangedEvent=new(ELeave) CVwsServerEvent_ScreenDeviceChanged(*this,*iEventQueue,threadWatcher,eventTimer); + CleanupStack::Pop(2); // threadWatcher, eventTimer - _ScreenDeviceChanged event is now the owner. + iEventQueue->ProcessEventL(screenDeviceChangedEvent); + } + +TInt CVwsServer::StartApp(const TUid& aAppUid,TThreadId& aThreadId) + { + LOG3(CVwsLog::ENormal,_L("Attempting to start app \"%x\""),aAppUid.iUid); + TRAPD(err,iAppStarter.StartAppL(aAppUid,aThreadId)); + return err; + } + +TInt CVwsServer::CheckViewExists(const TThreadId& aThreadId,const TVwsViewId& aViewId) + { + for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) + { + CSession2* baseSession=iSessionIter; + CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); + + if (thisSession->ClientThreadId()==aThreadId) + { + return thisSession->CheckViewExists(aViewId); + } + } + + return KErrNotFound; + } + +CVwsSession* CVwsServer::ActiveViewSession() + { + for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) + { + CSession2* baseSession=iSessionIter; + CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); + + if (thisSession->HasActiveView()) + { + return thisSession; + } + } + + return NULL; + } + +CVwsSession* CVwsServer::SessionByUid(const TUid& aAppUid) + { + for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) + { + CSession2* baseSession=iSessionIter; + CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); + + if (thisSession->AppUid()==aAppUid && !thisSession->Protected()) + { + return thisSession; + } + } + + return NULL; + } + +CVwsSession* CVwsServer::SessionByThreadIdAndAppUid(const TThreadId& aThreadId,const TUid& aAppUid) + { + for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) + { + CSession2* baseSession=iSessionIter; + CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); + + if (thisSession->ClientThreadId()==aThreadId && thisSession->AppUid()==aAppUid) + { + return thisSession; + } + } + + return NULL; + } + +CVwsSession* CVwsServer::SessionByThreadId(const TThreadId& aThreadId) + { + for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) + { + CSession2* baseSession=iSessionIter; + CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); + + if (thisSession->ClientThreadId()==aThreadId) + { + return thisSession; + } + } + + return NULL; + } + +TBool CVwsServer::IsViewActive(const TVwsViewId& aViewId) + { + for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) + { + CSession2* baseSession=iSessionIter; + CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); + + if (thisSession->HasActiveView()) + { + return thisSession->IsViewActive(aViewId); + } + } + + return EFalse; + } + +void CVwsServer::RequestDeactivateActiveViewL(const RMessage2& aMessage,const CVwsSession& aSession,TVwsCompleteRequest aCompleteRequest) + { + LOG2(CVwsLog::ENormal,_L("Received deactivate active view request, creating event to handle it")); + CVwsEventTimer* eventTimer=CVwsEventTimer::NewLC(iClientRequestTimeOut,iServerEventTimeOut); + CVwsServerEvent* deactivateActiveViewEvent=new(ELeave) CVwsServerEvent_DeactivateActiveView(*this,*iEventQueue,aMessage,aSession.ClientThreadId(),aCompleteRequest,eventTimer); + CleanupStack::Pop(); // eventTimer - _DeactivateActiveView event is now the owner. + iEventQueue->ProcessEventL(deactivateActiveViewEvent); + } + +void CVwsServer::RequestAppStartL(const RMessage2& aMessage,const TUid& aAppToStart) + { + LOG2(CVwsLog::ENormal,_L("Received start app request, creating event to handle it")); + CVwsThreadWatcher* threadWatcher=new(ELeave) CVwsThreadWatcher(); + CleanupStack::PushL(threadWatcher); + CVwsServerEvent* appStartEvent=new(ELeave) CVwsServerEvent_AppStart(*this,*iEventQueue,aMessage,aAppToStart,threadWatcher); + CleanupStack::Pop(); // threadWatcher + iEventQueue->ProcessEventL(appStartEvent); + } + +void CVwsServer::HandleDeactivation(const TVwsViewId& aDeactivatedViewId, const TVwsViewId& aActivatedViewId) + { + for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) + { + CSession2* baseSession=iSessionIter; + CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); + TRAP_IGNORE(thisSession->HandleDeactivationL(aDeactivatedViewId,aActivatedViewId)); + } + } + +void CVwsServer::HandleActivation(const TVwsViewId& aActivatedViewId, const TVwsViewId& aViewIdToBeDeactivated) + { + for (iSessionIter.SetToFirst();iSessionIter;iSessionIter++) + { + CSession2* baseSession=iSessionIter; + CVwsSession* thisSession=STATIC_CAST(CVwsSession*,baseSession); + TRAP_IGNORE(thisSession->HandleActivationL(aActivatedViewId,aViewIdToBeDeactivated)); + } + } + +void CVwsServer::MakeInterceptingWindowVisible() + { + if (iEnableServerBlankScreen) + { + iWServSessionHandler->DisplayWindow(); + } + } + +void CVwsServer::MakeInterceptingWindowInvisible() + { + if (iEnableServerBlankScreen) + { + iWServSessionHandler->HideWindow(); + } + } + +void CVwsServer::MakeInterceptingWindowVisibleAndUpdateScreen() + { + if (iEnableServerBlankScreen) + { + iWServSessionHandler->UpdateScreenAndDisplayWindow(); + } + } + +void CVwsServer::HandleSessionViewAddition(const TVwsViewId& aViewId, const TThreadId& aNewViewClientThreadId) + { + if (iViewAdditionObserver) + { + iViewAdditionObserver->HandleViewAdded(aViewId, aNewViewClientThreadId); + } + } + +void CVwsServer::HandleSessionRemoval(const TThreadId& aThreadId) + { + iEventQueue->HandleSessionRemoval(aThreadId); + } + +/* Check that the thread that has keyboard focus also has the active view. + * Activate a new view if not. + */ +void CVwsServer::CrossCheckForegroundTask() + { + //Get the focused window group; + RWsSession& wsSession=iWServSessionHandler->WsSession(); + TInt fgAppWgId=wsSession.GetFocusWindowGroup(); + if (fgAppWgId) + { + CVwsSession* activeSession=ActiveViewSession(); + TThreadId fgAppThreadId; + //Get the thread that owns this Window group. + if (wsSession.GetWindowGroupClientThreadId(fgAppWgId,fgAppThreadId)==KErrNotFound) + { + fgAppThreadId=TThreadId(0); + } + if (!(activeSession && activeSession->ClientThreadId()==fgAppThreadId) && SessionByThreadId(fgAppThreadId)) + { + LOG2(CVwsLog::ELoud,_L("Foreground app cross-check failed - notifying foreground app that it needs to activate a view")); + if(iCrossCheckUid!=KNullUid) + { + // We can't do anything about the leave here, so trap and ignore it + TRAP_IGNORE(SendCrossCheckToLauncherL(wsSession, fgAppWgId, ActiveView())); + } + else + { + TWsEvent event; + event.SetType(EEventUser); + *(TApaSystemEvent*)(event.EventData())=EApaSystemEventBroughtToForeground; + event.SetTimeNow(); + wsSession.SendEventToWindowGroup(fgAppWgId,event); + } + } + } + } + +void CVwsServer::HandleLastServerEventOnQueue() + { + MakeInterceptingWindowInvisible(); + if (iForegroundChangeWhileEventsOutstanding) + { + iForegroundChangeWhileEventsOutstanding=EFalse; + CrossCheckForegroundTask(); + } + } + +void CVwsServer::HandleForegroundTaskChange() + { + if (iEventQueue->Count()>0) + { + iForegroundChangeWhileEventsOutstanding=ETrue; + } + else + { + CrossCheckForegroundTask(); + } + } + + void CVwsServer::KickStartEventQ() + { + iEventQueue->KickStart(); + } + +CPolicyServer::TCustomResult CVwsServer::CustomSecurityCheckL(const RMessage2& aMsg, TInt& /*aAction*/, TSecurityInfo& /*aMissing*/) +//aAction is not set because default value to it is already set(CPolicyServer::EFailClient) +//aMissing is not set because it is not needed as we aren't overriding CheckFailedL + { + CPolicyServer::TCustomResult returnValue = CPolicyServer::EFail; + + // Check that the client either has SID of Eiksrvs or WriteDeviceData capability + if(aMsg.SecureId()==KEiksrvsSid || aMsg.HasCapability(ECapabilityWriteDeviceData)) + { + returnValue = CPolicyServer::EPass; + } + + return(returnValue); + } +void CVwsServer::GetPriorityForActiveObjectL(TInt& aPriority) + { + aPriority=iPrioritySet; + } + +struct TCrossCheckParam + { + TVwsViewId iActiveView; + TInt iFgAppWgId; + }; + +void CVwsServer::SetCrossCheckUid(const RMessage2& aMessage) + { + iCrossCheckUid.iUid=aMessage.Int0(); + } + +TUid CVwsServer::CrossCheckUid() const + { + return iCrossCheckUid; + } + +void CVwsServer::SendCrossCheckToLauncherL(RWsSession& aWsSession, TInt aFgAppWgId, const TVwsViewId& aActiveView) + { + TInt launcherWgId = 0; + const TInt KPriority = -1; + TInt wgCount = aWsSession.NumWindowGroups(KPriority); + if (wgCount) + { + CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC(aWsSession); + CArrayFixFlat* wgIdArray = new(ELeave) CArrayFixFlat(wgCount); + CleanupStack::PushL(wgIdArray); + User::LeaveIfError(aWsSession.WindowGroupList(KPriority, wgIdArray)); + const TInt KCount = wgIdArray->Count(); + for (TInt i = 0; i < KCount; ++i) + { + const TInt wgId = (*wgIdArray)[i]; + wgName->ConstructFromWgIdL(wgId); + if (wgName->AppUid() == iCrossCheckUid) + { + launcherWgId = wgId; + break; + } + } + CleanupStack::PopAndDestroy(2, wgName); // wgIdArray, wgName + } + + if (launcherWgId) + { + TWsEvent wsEvent; + wsEvent.SetType(EEventUser + 256); // Change this later + wsEvent.SetTimeNow(); + TCrossCheckParam* param = reinterpret_cast(wsEvent.EventData()); + param->iActiveView = aActiveView; + param->iFgAppWgId = aFgAppWgId; + aWsSession.SendEventToWindowGroup(launcherWgId, wsEvent); + } + }; + +void CVwsServer::SetWindowBackgroundColor(const RMessage2& aMessage) + { + TRgb color; + color.SetInternal(aMessage.Int0()); + iWServSessionHandler->SetWindowBackgroundColor(color); + } + +// Gets the active viewid of the foreground application +void CVwsServer::GetCurrentActiveViewId(TVwsViewId& aActiveViewId) + { + aActiveViewId = ActiveView(); + } + +// Tells if the application whose view is getting activated is in foreground or background +TBool CVwsServer::IsAppInForeground() + { + TBool isAppInForeground = EFalse; + RWsSession& wsSession = iWServSessionHandler->WsSession(); + TInt fgAppWgId = wsSession.GetFocusWindowGroup(); + if (fgAppWgId) + { + CVwsSession* activeSession = ActiveViewSession(); + TThreadId fgAppThreadId; + // Get the thread that owns this Window group. + // GetWindowGroupClientThreadId() either returns KErrNone or KErrNotFound error code + if (wsSession.GetWindowGroupClientThreadId(fgAppWgId,fgAppThreadId) == KErrNotFound) + { + fgAppThreadId = TThreadId(0); + } + + if (!(activeSession && (activeSession->ClientThreadId() == fgAppThreadId)) && SessionByThreadId(fgAppThreadId)) + { + isAppInForeground = ETrue; + } + } + return isAppInForeground; + } + +TBool CVwsServer::InitializationFinished() const + { + return iInitializationFinished; + } + +TInt CVwsServer::IsPriorityBoostBeforePanicEnabled()const + { + return iEnableBoostAppPriorityBeforePanic; + } + +void CVwsServer::HandleInitializationFinished() + { + iInitializationFinished = ETrue; + } + +void CVwsServer::BoostPriority(CVwsSession* aClient) + { + if (!aClient) + { + return; + } + if (!IsPriorityBoostBeforePanicEnabled()) + { + return; + } + + RThread starved; + if (starved.Open(aClient->ClientThreadId()) != KErrNone) + { + return; + } + + if (starved.ProcessPriority() < EPriorityForeground) + { + RProcess owningProcess; + TInt err = starved.Process(owningProcess); + if (err != KErrNone) + { + starved.Close(); + return; + } + owningProcess.SetPriority(EPriorityForeground); + owningProcess.Close(); + } + + starved.Close(); + } +