qthighway/xqserviceutil/src/xqrequestutil.cpp
changeset 26 3d09643def13
parent 8 71781823f776
--- 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 <w32std.h> // RWsSession
+#include <coemain.h>
+#include <QCoreApplication>
+
 #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<RWsSession::TWindowGroupChainInfo> 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");