0.9.21 release -- It changes so that the layer controlling function of GENIVI may...
[profile/ivi/ico-uxf-homescreen.git] / lib / system-controller / CicoSCServer.cpp
index 2ecb395..2be8fa5 100644 (file)
@@ -29,6 +29,7 @@ using namespace std;
 #include "CicoSCUserManager.h"
 #include "CicoSCUser.h"
 #include "CicoSCResourceManager.h"
+#include "CicoSCPolicyManager.h"
 
 class CicoSCUwsHandler
 {
@@ -62,8 +63,10 @@ CicoSCServer* CicoSCServer::ms_myInstance = NULL;
 //--------------------------------------------------------------------------
 CicoSCServer::CicoSCServer()
     : m_uwsContext(NULL), m_windowCtrl(NULL),
-      m_inputCtrl(NULL) , m_userMgr(NULL), m_resourceMgr(NULL)
+      m_inputCtrl(NULL) , m_userMgr(NULL), m_resourceMgr(NULL),
+      m_policyMgr(NULL), m_dispatchProcessing(false)
 {
+    CicoSCServer::ms_myInstance = this;
 }
 
 //--------------------------------------------------------------------------
@@ -73,7 +76,10 @@ CicoSCServer::CicoSCServer()
 //--------------------------------------------------------------------------
 CicoSCServer::~CicoSCServer()
 {
-    // TODO
+    if (NULL != m_uwsContext) {
+        ico_uws_close(m_uwsContext);
+    }
+    CicoSCServer::ms_myInstance = NULL;
 }
 
 //--------------------------------------------------------------------------
@@ -147,6 +153,19 @@ CicoSCServer::setResourceMgr(CicoSCResourceManager *resourceMgr)
 
 //--------------------------------------------------------------------------
 /**
+ *  @brief   set policy manager instance
+ *
+ *  @param [in] policyMgr policy manager instance
+ */
+//--------------------------------------------------------------------------
+void
+CicoSCServer::setPolicyMgr(CicoSCPolicyManager *policyMgr)
+{
+    m_policyMgr = policyMgr;
+}
+
+//--------------------------------------------------------------------------
+/**
  *  @brief   startup server
  *
  *  @param [in] port        websocket port
@@ -188,6 +207,52 @@ CicoSCServer::startup(int port, const char *protocol)
 
 //--------------------------------------------------------------------------
 /**
+ *  @brief  teardown server
+ */
+//--------------------------------------------------------------------------
+void
+CicoSCServer::teardown(void)
+{
+    ICO_TRA("CicoSCServer::teardown Enter");
+    {
+        std::list<CicoSCUwsHandler*>::iterator itr;
+        itr = m_uwsHandlerList.begin();
+        for (; itr !=  m_uwsHandlerList.end(); ++itr) {
+            if (NULL != (*itr)->ecoreFdHandler) {
+                ecore_main_fd_handler_del((*itr)->ecoreFdHandler);
+                (*itr)->ecoreFdHandler = NULL;
+            }
+            delete(*itr);
+        }
+        m_uwsHandlerList.clear();
+    }
+
+    {
+        std::list<CicoSCMessage*>::iterator itr;
+        itr = m_sendMsgQueue.begin();
+        for (; itr != m_sendMsgQueue.end(); ++itr) {
+            delete(*itr);
+        }
+        m_sendMsgQueue.clear();
+    }
+    
+    {
+        std::list<CicoSCCommand*>::iterator itr;
+        itr = m_recvCmdQueue.begin();
+        for (; itr != m_recvCmdQueue.end(); ++itr) {
+            delete(*itr);
+        }
+    }
+
+    if (NULL != m_uwsContext) {
+        ico_uws_close(m_uwsContext);
+        m_uwsContext = NULL;
+    }
+    ICO_TRA("CicoSCServer::teardown Leave");
+}
+
+//--------------------------------------------------------------------------
+/**
  *  @brief   add poll websocket file destructor
  *
  *  @param [in] handler  websocket handler
@@ -196,7 +261,7 @@ CicoSCServer::startup(int port, const char *protocol)
 void
 CicoSCServer::addPollFd(CicoSCUwsHandler *handler)
 {
-    ICO_DBG("CicoSCServer::addPollFd Enter(fd=%d)", handler->fd);
+    ICO_TRA("CicoSCServer::addPollFd Enter(fd=%d)", handler->fd);
     Ecore_Fd_Handler_Flags flags;
     flags = (Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_ERROR);
 
@@ -207,7 +272,7 @@ CicoSCServer::addPollFd(CicoSCUwsHandler *handler)
     ICO_DBG("Enqueue uwsHandler(0x%08x)", handler);
     m_uwsHandlerList.push_back(handler);
 
-    ICO_DBG("CicoSCServer::addPollFd Leave");
+    ICO_TRA("CicoSCServer::addPollFd Leave");
 }
 
 //--------------------------------------------------------------------------
@@ -220,10 +285,18 @@ CicoSCServer::addPollFd(CicoSCUwsHandler *handler)
 void
 CicoSCServer::delPollFd(CicoSCUwsHandler *handler)
 {
-    ICO_DBG("CicoSCServer::delPollFd Enter");
+    ICO_TRA("CicoSCServer::delPollFd Enter");
 
-    ecore_main_fd_handler_del(handler->ecoreFdHandler);
-    handler->ecoreFdHandler = NULL;
+    if (NULL == handler) {
+        ICO_WRN("handler is null");
+        ICO_TRA("CicoSCServer::delPollFd Leave");
+        return;
+    }
+
+    if (NULL != handler->ecoreFdHandler) {
+        ecore_main_fd_handler_del(handler->ecoreFdHandler);
+        handler->ecoreFdHandler = NULL;
+    }
 
     list<CicoSCUwsHandler*>::iterator itr;
     itr = m_uwsHandlerList.begin();
@@ -236,7 +309,7 @@ CicoSCServer::delPollFd(CicoSCUwsHandler *handler)
     }
     delete handler;
 
-    ICO_DBG("CicoSCServer::delPollFd Enter");
+    ICO_TRA("CicoSCServer::delPollFd Leave");
 }
 
 //--------------------------------------------------------------------------
@@ -251,11 +324,11 @@ CicoSCServer::delPollFd(CicoSCUwsHandler *handler)
 void
 CicoSCServer::dispatch(const CicoSCUwsHandler *handler)
 {
-    ICO_DBG("CicoSCServer::dispatch Enter(handler=0x%08x)", handler);
+//    ICO_TRA("CicoSCServer::dispatch Enter(handler=0x%08x)", handler);
 
     if (NULL == handler) {
         ICO_WRN("handler is null");
-        ICO_DBG("CicoSCServer::dispatch Leave");
+        ICO_TRA("CicoSCServer::dispatch Leave");
         return;
     }
 
@@ -264,10 +337,16 @@ CicoSCServer::dispatch(const CicoSCUwsHandler *handler)
     // There is a possibility that after calling ico_uws_service function,
     // the file is deleted.  Check whether handler not the disabled.
     if (false == isExistUwsHandler(handler)) {
-        ICO_DBG("CicoSCServer::dispatch Leave");
+        ICO_TRA("CicoSCServer::dispatch Leave");
+        return;
+    }
+
+    if (true == m_dispatchProcessing) {
+        ICO_TRA("CicoSCServer::dispatch Leave(disptch processing)");
         return;
     }
 
+    m_dispatchProcessing = true;
     list<CicoSCCommand*>::iterator itr;
     itr = m_recvCmdQueue.begin();
     while(itr != m_recvCmdQueue.end()) {
@@ -301,21 +380,22 @@ CicoSCServer::dispatch(const CicoSCUwsHandler *handler)
         }
         delete cmd;
     }
+    m_dispatchProcessing = false;
 
     if (NULL == handler->ecoreFdHandler) {
         ICO_ERR("ecoreFdHandler is null");
-        ICO_DBG("CicoSCServer::dispatch Leave");
+        ICO_TRA("CicoSCServer::dispatch Leave");
         return;
     }
 
     Eina_Bool flag = ecore_main_fd_handler_active_get(handler->ecoreFdHandler,
                                                       ECORE_FD_WRITE);
     if (EINA_TRUE == flag) {
-        ICO_DBG("start send message");
+//        ICO_DBG("start send message");
         list<CicoSCMessage*>::iterator send_itr;
         send_itr = m_sendMsgQueue.begin();
         while (send_itr != m_sendMsgQueue.end()) {
-            ICO_DBG("m_sendMsgQueue.size=%d", m_sendMsgQueue.size());
+//            ICO_DBG("m_sendMsgQueue.size=%d", m_sendMsgQueue.size());
             CicoSCMessage* msg = *send_itr;
             CicoSCUwsHandler *sendHandler = findUwsHandler(msg->getSendToAppid());
             if (handler != sendHandler) {
@@ -325,13 +405,13 @@ CicoSCServer::dispatch(const CicoSCUwsHandler *handler)
             send_itr = m_sendMsgQueue.erase(send_itr);
             ICO_DBG("Dequeue Message(id=%d)", msg->getId());
             if ((NULL != sendHandler) && (true == sendHandler->serviceFlag)) {
+                const char *data = msg->getData();
                 ICO_DBG("<<<SEND appid=%s id=0x%08x msg=%s",
-                        sendHandler->appid.c_str(), sendHandler->id, msg->getData());
-                ICO_DBG("called: ico_usw_send called(context=0x%08x id=0x%08x)",
-                        sendHandler->uwsContext, sendHandler->id);
+                        sendHandler->appid.c_str(), sendHandler->id, data);
+//                ICO_DBG("called: ico_usw_send called(context=0x%08x id=0x%08x)",
+//                        sendHandler->uwsContext, sendHandler->id);
                 ico_uws_send(sendHandler->uwsContext, sendHandler->id,
-                             (unsigned char *)msg->getData(),
-                             strlen(msg->getData()));
+                             (unsigned char *)data, strlen(data));
 
                 delete msg;
 
@@ -345,7 +425,7 @@ CicoSCServer::dispatch(const CicoSCUwsHandler *handler)
         ecore_main_fd_handler_active_set(handler->ecoreFdHandler, flags);
     }
 
-    ICO_DBG("CicoSCServer::dispatch Leave");
+//    ICO_TRA("CicoSCServer::dispatch Leave");
 }
 
 //--------------------------------------------------------------------------
@@ -361,7 +441,7 @@ CicoSCServer::dispatch(const CicoSCUwsHandler *handler)
 int
 CicoSCServer::sendMessage(const string & appid, CicoSCMessage* msg)
 {
-    ICO_DBG("CicoSCServer::sendMessage Enter(appid=%s, msg=%s)",
+    ICO_TRA("CicoSCServer::sendMessage Enter(appid=%s, msg=%s)",
             appid.c_str(), msg->getData());
 
     msg->setSendToAppid(appid);
@@ -380,7 +460,7 @@ CicoSCServer::sendMessage(const string & appid, CicoSCMessage* msg)
         dispatch(handler);
     }
 
-    ICO_DBG("CicoSCServer::sendMessage Leave(EOK)");
+    ICO_TRA("CicoSCServer::sendMessage Leave(EOK)");
     return ICO_SYC_EOK;
 }
 
@@ -396,6 +476,12 @@ CicoSCServer::sendMessage(const string & appid, CicoSCMessage* msg)
 int
 CicoSCServer::sendMessageToHomeScreen(CicoSCMessage* msg)
 {
+    // if user change processing(homescree is not running)
+    if (true == m_userMgr->isStoppingNow()) {
+        ICO_DBG("homescreen not running");
+        return ICO_SYC_ENOENT;
+    }
+
     const CicoSCUser *loginUser = m_userMgr->getLoginUser();
     if (NULL == loginUser) {
         ICO_WRN("homescreen unknown");
@@ -444,7 +530,7 @@ CicoSCServer::uwsReceiveEventCB(const struct ico_uws_context *context,
 Eina_Bool
 CicoSCServer::ecoreFdCallback(void *data, Ecore_Fd_Handler *ecoreFdhandler)
 {
-    ICO_DBG("CicoSCServer::ecoreFdCallback Enter");
+//    ICO_TRA("CicoSCServer::ecoreFdCallback Enter");
 
     CicoSCUwsHandler *handler = NULL;
     handler =  static_cast<CicoSCServer*>(data)->findUwsHandler(ecoreFdhandler);
@@ -452,7 +538,7 @@ CicoSCServer::ecoreFdCallback(void *data, Ecore_Fd_Handler *ecoreFdhandler)
         static_cast<CicoSCServer*>(data)->dispatch(handler);
     }
 
-    ICO_DBG("CicoSCServer::ecoreFdCallback Leave");
+//    ICO_TRA("CicoSCServer::ecoreFdCallback Leave");
     return ECORE_CALLBACK_RENEW;
 }
 
@@ -474,7 +560,21 @@ CicoSCServer::receiveEventCB(const struct ico_uws_context *context,
                              const ico_uws_detail         *detail,
                              void                         *user_data)
 {
-    ICO_DBG("CicoSCServer::receiveEventCB Enter");
+//    ICO_TRA("CicoSCServer::receiveEventCB Enter");
+
+    switch (event) {
+    case ICO_UWS_EVT_CLOSE:
+        ICO_DBG(">>>RECV ICO_UWS_EVT_CLOSE(id=0x%08x)", (int)id);
+//        ICO_TRA("CicoSCServer::receiveEventCB Leave");
+        return;
+    case ICO_UWS_EVT_ERROR:
+        ICO_DBG(">>>RECV ICO_UWS_EVT_ERROR(id=0x%08x, err=%d)", 
+                (int)id, detail->_ico_uws_error.code);
+//        ICO_TRA("CicoSCServer::receiveEventCB Leave");
+        return;
+    default:
+        break;
+    }
 
     // find handler
     CicoSCUwsHandler *handler = findUwsHandler(context, id);
@@ -492,6 +592,7 @@ CicoSCServer::receiveEventCB(const struct ico_uws_context *context,
         break;
     case ICO_UWS_EVT_CLOSE:
         ICO_DBG(">>>RECV ICO_UWS_EVT_CLOSE(id=0x%08x)", (int)id);
+        delete handler;
         break;
     case ICO_UWS_EVT_RECEIVE:
     {
@@ -507,6 +608,7 @@ CicoSCServer::receiveEventCB(const struct ico_uws_context *context,
         if (cmd->cmdid == MSG_CMD_SEND_APPID) {
             if (0 == cmd->appid.length()) {
                 ICO_WRN("command argument invalid appid null");
+                delete cmd;
                 break;
             }
             handler->appid = cmd->appid;
@@ -520,6 +622,8 @@ CicoSCServer::receiveEventCB(const struct ico_uws_context *context,
 
             ecore_main_fd_handler_active_set(handler->ecoreFdHandler, flags);
 
+            notifyConnected(handler->appid);
+            delete cmd;
             break;
         }
         
@@ -528,25 +632,79 @@ CicoSCServer::receiveEventCB(const struct ico_uws_context *context,
         m_recvCmdQueue.push_back(cmd);
         break;
     }
-    case ICO_UWS_EVT_ERROR:
-        ICO_DBG(">>>RECV ICO_UWS_EVT_ERROR(id=0x%08x, err=%d)", 
-                (int)id, detail->_ico_uws_error.code);
-        break;
     case ICO_UWS_EVT_ADD_FD:
         ICO_DBG(">>>RECV ICO_UWS_EVT_ADD_FD(id=0x%08x, fd=%d)",
-                    (int)id, detail->_ico_uws_fd.fd);
+                (int)id, detail->_ico_uws_fd.fd);
         handler->fd = detail->_ico_uws_fd.fd;
         addPollFd(handler);
         break;
     case ICO_UWS_EVT_DEL_FD:
-        ICO_DBG(">>>RECV ICO_UWS_EVT_DEL_FD(id=0x%08x, fd=%d)",
-                    (int)id, detail->_ico_uws_fd.fd);
+        ICO_DBG(">>>RECV ICO_UWS_EVT_DEL_FD(id=0x%08x, fd=%d, appid=%s)",
+                (int)id, detail->_ico_uws_fd.fd, handler->appid.c_str());
+        clearRecvCmdQueue(handler->appid);
+        clearSendMsgQueue(handler->appid);
         delPollFd(handler);
         break;
     default:
         break;
     }
-    ICO_DBG("CicoSCServer::receiveEventCB Leave");
+//    ICO_TRA("CicoSCServer::receiveEventCB Leave");
+}
+
+//--------------------------------------------------------------------------
+/**
+ *  @brief   clear receive command queue
+ *
+ *  @param [in] appid   clear command application id
+ */
+//--------------------------------------------------------------------------
+void
+CicoSCServer::clearRecvCmdQueue(const std::string & appid)
+{
+    ICO_TRA("CicoSCServer::clearCmdQueue Enter(appid=%s)", appid.c_str());
+
+    std::list<CicoSCCommand*>::iterator itr;
+    itr = m_recvCmdQueue.begin();
+    for (; itr != m_recvCmdQueue.end(); ) {
+        if (0 == appid.compare((*itr)->appid)) {
+            ICO_DBG("Dequeue command(0x%08x)", (*itr)->cmdid);
+            delete *itr;
+            itr = m_recvCmdQueue.erase(itr);
+        }
+        else {
+            ++itr;
+        }
+    }
+
+    ICO_TRA("CicoSCServer::clearCmdQueue Leave")
+}
+
+//--------------------------------------------------------------------------
+/**
+ *  @brief   clear send message queue
+ *
+ *  @param [in] appid   clear message application id
+ */
+//--------------------------------------------------------------------------
+void
+CicoSCServer::clearSendMsgQueue(const std::string & appid)
+{
+    ICO_TRA("CicoSCServer::clearMsgQueue Enter(appid=%s)", appid.c_str())
+
+    std::list<CicoSCMessage*>::iterator itr;
+    itr = m_sendMsgQueue.begin();
+    while(itr != m_sendMsgQueue.end()) {
+        if (0 == appid.compare((*itr)->getSendToAppid())) {
+            ICO_DBG("Dequeue Message(id=%d)", (*itr)->getId());
+            delete *itr;
+            itr = m_sendMsgQueue.erase(itr);
+        }
+        else {
+            ++itr;
+        }
+    }
+
+    ICO_TRA("CicoSCServer::clearMsgQueue Leave")
 }
 
 //--------------------------------------------------------------------------
@@ -566,8 +724,8 @@ CicoSCServer::findUwsHandler(const struct ico_uws_context *context,
     list<CicoSCUwsHandler*>::iterator itr;
     itr = m_uwsHandlerList.begin();
     for (; itr != m_uwsHandlerList.end(); ++itr) {
-        ICO_DBG("handler->context=%p handler->id=%p context=%p id=%p",
-                (*itr)->uwsContext, (*itr)->id, context, id);
+//        ICO_DBG("handler->context=%p handler->id=%p context=%p id=%p",
+//                (*itr)->uwsContext, (*itr)->id, context, id);
         if (((*itr)->uwsContext == context) &&
             ((*itr)->id == id)) {
             return *itr;
@@ -613,8 +771,8 @@ CicoSCServer::findUwsHandler(const string & appid)
     list<CicoSCUwsHandler*>::iterator itr;
     itr = m_uwsHandlerList.begin();
     for (; itr != m_uwsHandlerList.end(); ++itr) {
-        ICO_DBG("handler->id=%p handler->appid=%s appid=%s",
-                (*itr)->id, (*itr)->appid.c_str(), appid.c_str());
+//        ICO_DBG("handler->id=%p handler->appid=%s appid=%s",
+//                (*itr)->id, (*itr)->appid.c_str(), appid.c_str());
         if ((*itr)->appid == appid) {
             return *itr;
         }
@@ -643,4 +801,28 @@ CicoSCServer::isExistUwsHandler(const CicoSCUwsHandler *handler)
     }
     return false;
 }
+
+//--------------------------------------------------------------------------
+/**
+ *  @brief  notify information to homescreen on connected
+ *
+ *  @param [in] appid   application id
+ */
+//--------------------------------------------------------------------------
+void
+CicoSCServer::notifyConnected(const std::string & appid)
+{
+    const CicoSCUser *loginUser = m_userMgr->getLoginUser();
+    if (NULL == loginUser) {
+        ICO_WRN("homescreen unknown");
+        return;
+    }
+
+    // if appid equal homescreen
+    if (0 == loginUser->homescreen.compare(appid)) {
+        if (NULL != m_policyMgr) {
+            m_policyMgr->notifyConnected(appid);
+        }
+    }
+}
 // vim:set expandtab ts=4 sw=4: