diff -r 9d760f716ca8 -r 3d09643def13 qthighway/xqserviceutil/src/xqrequestutil.cpp --- a/qthighway/xqserviceutil/src/xqrequestutil.cpp Thu Sep 02 21:20:48 2010 +0300 +++ b/qthighway/xqserviceutil/src/xqrequestutil.cpp Fri Sep 17 08:34:25 2010 +0300 @@ -22,8 +22,227 @@ #include "xqservicelog.h" #include "xqserviceerrdefs.h" +#include // RWsSession +#include +#include + #include "xqrequestutil.h" +// ======== LOCAL CLASSES ======== + +class CParentObserver: public CActive +{ +public: + + /** + * Starts to observe if parent is still running and close embedded view when parent closed + */ + static void closeWhenParentClosedL(); + + /** + * C++ destructor. + */ + virtual ~CParentObserver(); + +protected: + + // @see CActive + virtual void RunL(); + + // @see CActive + virtual void DoCancel(); + + // @see CActive + virtual TInt RunError( TInt aError ); + +private: + + CParentObserver(); + void ConstructL(); + void IssueRequest(); + void HandleWsEventL(const TWsEvent &aEvent); + +private: // Data + + class ParentObserverDestructor + { + public: + ParentObserverDestructor():iObserver(NULL){} + + ~ParentObserverDestructor() + { + delete iObserver; + } + + CParentObserver* iObserver; + }; + + static ParentObserverDestructor iInstance; + + /** Window server session */ + RWsSession iWsSession; + + /** Window group for receiving window server events */ + RWindowGroup* iWindowGroup; +}; + +CParentObserver::ParentObserverDestructor CParentObserver::iInstance; + +// --------------------------------------------------------------------------- +// C++ constructor. +// --------------------------------------------------------------------------- +// +CParentObserver::CParentObserver(): + CActive(CActive::EPriorityStandard) +{ + CActiveScheduler::Add(this); +} + +// --------------------------------------------------------------------------- +// Symbian 2nd phase constructor. +// --------------------------------------------------------------------------- +// +void CParentObserver::ConstructL() +{ + // Connect to window server server + User::LeaveIfError(iWsSession.Connect()); + + // Construct window group + iWindowGroup = new(ELeave) RWindowGroup(iWsSession); + User::LeaveIfError( iWindowGroup->Construct((TUint32)this, EFalse)); + User::LeaveIfError(iWindowGroup->EnableGroupChangeEvents()); +} + +// --------------------------------------------------------------------------- +// Starts to observe if parent is still running and close embedded view when parent closed +// --------------------------------------------------------------------------- +// +void CParentObserver::closeWhenParentClosedL() +{ + if (!iInstance.iObserver) { + iInstance.iObserver = new (ELeave) CParentObserver(); + iInstance.iObserver->ConstructL(); + } + + iInstance.iObserver->IssueRequest(); +} + +// --------------------------------------------------------------------------- +// C++ destructor. +// --------------------------------------------------------------------------- +// +CParentObserver::~CParentObserver() +{ + Cancel(); + + // Cleanup window group + if(iWindowGroup) { + iWindowGroup->DisableGroupChangeEvents(); + iWindowGroup->Close(); + delete iWindowGroup; + } + + // Cleanup window server session + iWsSession.Close(); +} + +//------------------------------------------------------------------------------ +// CParentObserver::IssueRequest +//------------------------------------------------------------------------------ +// +void CParentObserver::IssueRequest() +{ + if(!IsActive()) { + // Request events from window server + iWsSession.EventReady(&iStatus); + SetActive(); + } +} + +//------------------------------------------------------------------------------ +// CParentObserver::HandleWsEventL +//------------------------------------------------------------------------------ +// +void CParentObserver::HandleWsEventL(const TWsEvent &aEvent) +{ + if (aEvent.Type() == EEventWindowGroupsChanged) { + RWindowGroup rootWG = CCoeEnv::Static()->RootWin(); + int rootWGId = rootWG.Identifier(); + + RArray list; + CleanupClosePushL(list); + iWsSession.WindowGroupList(&list); + + for(int idx = 0; idx < list.Count(); idx++) + { + RWsSession::TWindowGroupChainInfo info = list[idx]; + if (info.iId == rootWGId && info.iParentId <= 0) { + qApp->quit(); + break; + } + } + CleanupStack::PopAndDestroy(); // list + } +} + +//------------------------------------------------------------------------------ +// CParentObserver::RunL +//------------------------------------------------------------------------------ +// +void CParentObserver::RunL() +{ + TInt err = iStatus.Int(); + if(err == KErrNone) { + // No errors occured, fetch event + TWsEvent wsEvent; + iWsSession.GetEvent(wsEvent); + + // Continue listening + IssueRequest(); + + // Forward event to observer + HandleWsEventL(wsEvent); + } + else { + // Continue listening + IssueRequest(); + } +} + +//------------------------------------------------------------------------------ +// CParentObserver::DoCancel +//------------------------------------------------------------------------------ +// +void CParentObserver::DoCancel() +{ + // Cancel event ready from window server + iWsSession.EventReadyCancel(); +} + +//------------------------------------------------------------------------------ +// CParentObserver::RunError +//------------------------------------------------------------------------------ +// +TInt CParentObserver::RunError(TInt /*aError*/) +{ + // Issue a new request + IssueRequest(); + + return KErrNone; +} + +/*! + Observes if client is still running and close embedded view when client closed +*/ +void XQServiceUtils::closeWhenClientClosed() +{ + XQSERVICE_DEBUG_PRINT("XQServiceUtil::closeEVWhenClientClosed"); + + TRAPD(err, CParentObserver::closeWhenParentClosedL()); + + XQSERVICE_DEBUG_PRINT("XQServiceUtil::closeEVWhenClientClosed return value: ", err); +} + XQRequestUtil::XQRequestUtil() { XQSERVICE_DEBUG_PRINT("XQRequestUtil::XQRequestUtil");