Reorganize directory structure 36/248136/1
authorJi-hoon Lee <dalton.lee@samsung.com>
Mon, 23 Nov 2020 03:11:02 +0000 (12:11 +0900)
committerJi-hoon Lee <dalton.lee@samsung.com>
Mon, 23 Nov 2020 03:11:02 +0000 (12:11 +0900)
Change-Id: Ide6e34f653e78ec0e5474015dca62e277fa81645

CMakeLists.txt
src/legacy_support/web_helper_agent.cpp [deleted file]
src/legacy_support/web_helper_agent.h [deleted file]
src/legacy_support/websocket.cpp [deleted file]
src/legacy_support/websocket.h [deleted file]
src/sclconnection-isf.cpp
src/sclcoreui-efl.h
src/web_helper_agent.cpp [new file with mode: 0644]
src/web_helper_agent.h [new file with mode: 0644]
src/websocket.cpp [new file with mode: 0644]
src/websocket.h [new file with mode: 0644]

index 2fe6e3330c29fd4893682eaf6bb87b8650e025bc..928a94042b917571d985af3e0c020c8770000b03 100644 (file)
@@ -22,7 +22,6 @@ MESSAGE(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
 
 INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src
                     ${CMAKE_SOURCE_DIR}/src/include
-                    ${CMAKE_SOURCE_DIR}/src/legacy_support
                    )
 
 INCLUDE(FindPkgConfig)
@@ -47,8 +46,8 @@ ENDIF(with_wayland)
 IF (with_websocket)
         ADD_DEFINITIONS("-DWEBSOCKET")
         SET(SRCS ${SRCS}
-            src/legacy_support/websocket.cpp
-            src/legacy_support/web_helper_agent.cpp)
+            src/websocket.cpp
+            src/web_helper_agent.cpp)
         SET(PKGS_CHECK_MODULES ${PKGS_CHECK_MODULES} libwebsockets)
 ENDIF(with_websocket)
 
diff --git a/src/legacy_support/web_helper_agent.cpp b/src/legacy_support/web_helper_agent.cpp
deleted file mode 100644 (file)
index 1d3cfc5..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (c) 2012 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <stdio.h>
-#include <dlog.h>
-
-#include "web_helper_agent.h"
-
-#include "websocket.h"
-#include "sclcoreimpl.h"
-
-using namespace scl;
-
-typedef struct {
-    int major_version;
-    WEB_HELPER_AGENT_TYPE agent_type;
-} WEB_HELPER_AGENT_TYPES_FOR_VERSIONS;
-
-static WEB_HELPER_AGENT_TYPES_FOR_VERSIONS web_helper_agent_types_for_versions[] = {
-    {1, WEB_HELPER_AGENT_WEBSOCKET}, /* Major version 1 indicates that it uses websocket for communication */
-};
-
-static int WEB_HELPER_AGENT_TYPES_FOR_VERSIONS_NUM = \
-    sizeof(web_helper_agent_types_for_versions) / sizeof(WEB_HELPER_AGENT_TYPES_FOR_VERSIONS);
-
-WEB_HELPER_AGENT_TYPE CWebHelperAgent::get_web_helper_agent_type_from_major_version(int version)
-{
-    for (int loop = 0;loop < WEB_HELPER_AGENT_TYPES_FOR_VERSIONS_NUM;loop++) {
-        if (web_helper_agent_types_for_versions[loop].major_version == version) {
-            return web_helper_agent_types_for_versions[loop].agent_type;
-        }
-    }
-    return WEB_HELPER_AGENT_UNKNOWN;
-}
-
-CWebHelperAgent* CWebHelperAgent::create_web_helper_agent(WEB_HELPER_AGENT_TYPE type)
-{
-    CWebHelperAgent *ret = NULL;
-    if (type == WEB_HELPER_AGENT_WEBSOCKET) {
-        ret = new CWebHelperAgentWebSocket;
-    }
-    return ret;
-}
-
-void CWebHelperAgent::destroy_web_helper_agent(CWebHelperAgent* agent)
-{
-    if (agent) delete agent;
-}
-
-CWebHelperAgent::CWebHelperAgent()
-{
-}
-
-CWebHelperAgent::~CWebHelperAgent()
-{
-}
-
-bool CWebHelperAgent::init()
-{
-    return true;
-}
-
-bool CWebHelperAgent::exit()
-{
-    return true;
-}
-
-void CWebHelperAgent::signal(int sig)
-{
-}
-
-void CWebHelperAgent::log(const char *str)
-{
-    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
-    if (impl) {
-        //impl->logise_log(str);
-    }
-}
-
-void CWebHelperAgent::commit_string(const char *str)
-{
-    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
-    if (impl) {
-        impl->commit_string(-1, "", str);
-    }
-}
-
-void CWebHelperAgent::update_preedit_string(const char *str)
-{
-    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
-    if (impl) {
-        impl->update_preedit_string(-1, "", str);
-    }
-}
-
-void CWebHelperAgent::send_key_event(unsigned int key, unsigned int key_mask)
-{
-    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
-    if (impl) {
-        impl->send_key_event(-1, "", key, key_mask);
-    }
-}
-
-void CWebHelperAgent::forward_key_event(unsigned int key)
-{
-    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
-    if (impl) {
-        impl->forward_key_event(-1, "", key, scim::SCIM_KEY_NullMask);
-    }
-}
-
-void CWebHelperAgent::set_keyboard_sizes(int portrait_width, int portrait_height, int landscape_width, int landscape_height)
-{
-    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
-    if (impl) {
-        SclSize portrait, landscape;
-        portrait.width = portrait_width;
-        portrait.height = portrait_height;
-        landscape.width = landscape_width;
-        landscape.height = landscape_height;
-        impl->set_keyboard_size_hints(portrait, landscape);
-    }
-}
-
-void CWebHelperAgent::set_selection(int start_index, int end_index)
-{
-    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
-    if (impl) {
-        impl->set_selection(start_index, end_index);
-    }
-}
-
-void CWebHelperAgent::get_selection()
-{
-    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
-    if (impl) {
-        //impl->get_selection(-1, "", );
-    }
-}
-
-void CWebHelperAgent::get_surrounding_text(int maxlen_before, int maxlen_after)
-{
-    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
-    if (impl) {
-        impl->get_surrounding_text("", maxlen_before, maxlen_after);
-    }
-}
-
-void CWebHelperAgent::delete_surrounding_text(int offset, int len)
-{
-    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
-    if (impl) {
-        impl->delete_surrounding_text(offset, len);
-    }
-}
-
-std::string CMagicKeyManager::get_magic_key()
-{
-    static std::string current_magic_key;
-
-    /* If we don't have magic key generated yet */
-    if (current_magic_key.length() != MAGIC_KEY_LENGTH) {
-        char magic_key[MAGIC_KEY_LENGTH + 1];
-        /* We are going to generate a magic key that contains ascii characters in the range of '0' to 'z' */
-        const char magic_key_range_lower = '0';
-        const char magic_key_range_upper = 'Z';
-
-        unsigned int seed = time(NULL);
-        for (int loop = 0;loop < MAGIC_KEY_LENGTH;loop++) {
-            magic_key[loop] = (rand_r(&seed) % (magic_key_range_upper - magic_key_range_lower)) + magic_key_range_lower;
-        }
-        magic_key[MAGIC_KEY_LENGTH] = '\0';
-
-        current_magic_key = magic_key;
-    }
-
-    return current_magic_key;
-}
diff --git a/src/legacy_support/web_helper_agent.h b/src/legacy_support/web_helper_agent.h
deleted file mode 100644 (file)
index c05c572..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2012 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef _WEB_HELPER_AGENT_H_
-#define _WEB_HELPER_AGENT_H_
-
-#define MAGIC_KEY_LENGTH 32
-#define VERSION_DELIMITER '.'
-#define VERSION_TOKEN_NUM 2 // We are expecting 2 version tokens : MAJOR and MINOR
-
-#include <string>
-#include <sstream>
-#include <vector>
-
-class CStringTokenizer
-{
-public:
-    static std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
-        unsigned int loop = 0;
-        unsigned int start = 0;
-        for (loop = 0;loop < s.length();loop++) {
-            if (s.at(loop) == delim) {
-                std::string item = s.substr(start, loop - start);
-                elems.push_back(item);
-                start = loop + 1;
-            }
-        }
-        std::string item = s.substr(start, loop - start);
-        elems.push_back(item);
-        return elems;
-    }
-
-    static std::vector<std::string> split(const std::string &s, char delim) {
-        std::vector<std::string> elems;
-        split(s, delim, elems);
-        return elems;
-    }
-};
-
-typedef enum {
-    WEB_HELPER_AGENT_UNKNOWN,
-    WEB_HELPER_AGENT_WEBSOCKET,
-    WEB_HELPER_AGENT_DIRECT,
-} WEB_HELPER_AGENT_TYPE;
-
-class CMagicKeyManager
-{
-public:
-    static std::string get_magic_key();
-};
-
-class CWebHelperAgent
-{
-public:
-    CWebHelperAgent();
-    virtual ~CWebHelperAgent();
-
-    virtual bool init();
-    virtual bool exit();
-
-    virtual bool run() { return false; }
-    virtual void signal(int sig);
-
-    virtual void on_init() {}
-    virtual void on_exit() {}
-
-    virtual void on_focus_in(int ic) {}
-    virtual void on_focus_out(int ic) {}
-
-    virtual void on_show(int ic) {}
-    virtual void on_hide(int ic) {}
-
-    virtual void on_set_rotation(int degree) {}
-
-    virtual void on_update_cursor_position(int ic, int cursor_pos) {}
-    virtual void on_update_surrounding_text(int ic, const char *text, int cursor) {}
-    virtual void on_update_selection(int ic, const char *text) {}
-
-    virtual void on_set_language(unsigned int language) {}
-
-    virtual void on_set_imdata(char *buf, unsigned int len) {}
-    virtual void on_get_imdata(char **buf, unsigned int *len) {}
-
-    virtual void on_set_return_key_type(unsigned int type) {}
-    virtual void on_get_return_key_type(unsigned int *type) {}
-
-    virtual void on_set_return_key_disable(unsigned int disabled) {}
-    virtual void on_get_return_key_disable(unsigned int *disabled) {}
-
-    virtual void on_set_layout(unsigned int layout) {}
-    virtual void on_get_layout(unsigned int *layout) {}
-
-    virtual void on_reset_input_context(int ic) {}
-
-    virtual void on_process_key_event(unsigned int code, unsigned int mask, unsigned int layout, unsigned int *ret) {}
-
-
-    virtual void log(const char *str);
-    virtual void commit_string(const char *str);
-    virtual void update_preedit_string(const char *str);
-    virtual void send_key_event(unsigned int key, unsigned int key_mask);
-    virtual void forward_key_event(unsigned int key);
-    virtual void set_keyboard_sizes(int portrait_width, int portrait_height, int landscape_width, int landscape_height);
-    virtual void set_selection(int start_index, int end_index);
-    virtual void get_selection();
-    virtual void get_surrounding_text(int maxlen_before, int maxlen_after);
-    virtual void delete_surrounding_text(int offset, int len);
-
-public:
-    static WEB_HELPER_AGENT_TYPE get_web_helper_agent_type_from_major_version(int version);
-    static CWebHelperAgent* create_web_helper_agent(WEB_HELPER_AGENT_TYPE type);
-    static void destroy_web_helper_agent(CWebHelperAgent* agent);
-};
-
-#endif // _WEB_HELPER_AGENT_H_
diff --git a/src/legacy_support/websocket.cpp b/src/legacy_support/websocket.cpp
deleted file mode 100644 (file)
index 2ae2565..0000000
+++ /dev/null
@@ -1,1252 +0,0 @@
-/*
- * Copyright (c) 2012 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <string.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <Ecore.h>
-#include <Ecore_IMF.h>
-#include <dlog.h>
-
-#include "websocket.h"
-
-#include <syslog.h>
-#include <signal.h>
-
-#include <libwebsockets.h>
-
-#ifdef WAYLAND
-#define EFL_BETA_API_SUPPORT
-#include <Ecore_Wl2.h>
-#endif
-
-#define WEBSOCKET_PORT 7681
-
-#define RECVED_MESSAGE "recved"
-#define MESSAGE_LEFT "left"
-
-pthread_t g_ws_server_thread = (pthread_t)NULL;
-pthread_mutex_t g_ws_server_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-pthread_cond_t g_ws_query_condition = PTHREAD_COND_INITIALIZER;
-pthread_mutex_t g_ws_query_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-bool g_ws_server_exit = false;
-struct lws_context *g_ws_server_context = NULL;
-
-CWebHelperAgentWebSocket* CWebHelperAgentWebSocket::m_current_instance = NULL;
-
-int force_exit = 0;
-
-enum protocols {
-    /* always first */
-    PROTOCOL_HTTP = 0,
-
-    PROTOCOL_KEYBOARD,
-
-    /* always last */
-    MAX_PROTOCOL_COUNT
-};
-
-struct per_session_data__http {
-    int fd;
-};
-
-static int callback_http(struct lws *wsi,
-        enum lws_callback_reasons reason,
-        void *user, void *in, size_t len)
-{
-    return 0;
-}
-
-struct per_session_data__keyboard {
-    int session_id;
-    int valid;
-    int need_init;
-    int initialized;
-};
-
-static int callback_keyboard(struct lws *wsi,
-        enum lws_callback_reasons reason,
-        void *user, void *in, size_t len);
-
-static struct lws_protocols protocols[] = {
-    {
-        "http-only",
-        callback_http,
-        sizeof(struct per_session_data__http),
-        0,
-    },
-    {
-        "keyboard-protocol",
-        callback_keyboard,
-        sizeof(struct per_session_data__keyboard),
-        32,
-    },
-    { NULL, NULL, 0, 0 }
-};
-
-
-static int callback_client(struct lws *wsi,
-    enum lws_callback_reasons reason,
-    void *user, void *in, size_t len)
-{
-    switch (reason) {
-    case LWS_CALLBACK_CLIENT_ESTABLISHED:
-        LOGD("[ClientTest] Connection established");
-        break;
-
-    case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
-        LOGD("[ClientTest] Connection error");
-        break;
-
-    case LWS_CALLBACK_CLOSED:
-        LOGD("[ClientTest] Connection closed");
-        break;
-
-    default:
-        break;
-    }
-
-    return 0;
-}
-
-int test_client_connection(void)
-{
-    struct lws_context *context = NULL;
-    struct lws_context_creation_info context_info;
-    struct lws_client_connect_info connect_info;
-    struct lws *wsi = NULL;
-
-    memset(&context_info, 0, sizeof context_info);
-    memset(&connect_info, 0, sizeof(connect_info));
-
-    const int protocols_num = sizeof(protocols) / sizeof(lws_protocols);
-    static struct lws_protocols client_protocols[protocols_num];
-
-    memcpy(&client_protocols, protocols, sizeof(protocols));
-    for (int loop = 0; loop < protocols_num - 1; loop++) {
-        client_protocols[loop].callback = callback_client;
-    }
-
-    context_info.port = CONTEXT_PORT_NO_LISTEN;
-    context_info.protocols = protocols;
-    context_info.gid = -1;
-    context_info.uid = -1;
-
-    context = lws_create_context(&context_info);
-    LOGD("[ClientTest] create_context : %p", context);
-    if (context == NULL) {
-        return -1;
-    }
-
-    connect_info.address = "localhost";
-    connect_info.port = WEBSOCKET_PORT;
-    connect_info.path = "/";
-    connect_info.context = context;
-    connect_info.ssl_connection = 0;
-    connect_info.host = connect_info.address;
-    connect_info.origin = connect_info.address;
-    connect_info.ietf_version_or_minus_one = -1;
-    connect_info.protocol = "keyboard-protocol";
-
-    wsi = lws_client_connect_via_info(&connect_info);
-    LOGD("[ClientTest] wsi created : %p", wsi);
-
-    if (wsi) {
-        lws_service(context, 50);
-    }
-
-    lws_context_destroy(context);
-
-    return 0;
-}
-
-static Ecore_Timer *g_flush_server_recv_buffer_timer = NULL;
-static std::string server_recv_buffer;
-static Eina_Bool flush_server_recv_buffer_func(void *user)
-{
-    LOGD("flushing recv buffer");
-    CWebHelperAgentWebSocket *agent = CWebHelperAgentWebSocket::get_current_instance();
-    struct per_session_data__keyboard *pss = (struct per_session_data__keyboard *)user;
-
-    if (g_flush_server_recv_buffer_timer)
-        ecore_timer_del(g_flush_server_recv_buffer_timer);
-    g_flush_server_recv_buffer_timer = NULL;
-
-    if (!agent || !pss) return ECORE_CALLBACK_CANCEL;
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    ISE_MESSAGE message = CISEMessageSerializer::deserialize(server_recv_buffer);
-    server_recv_buffer.clear();
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_LOGIN]) == 0) {
-        /*
-           if (message.values.at(0).compare(CMagicKeyManager::get_magic_key()) == 0) {
-           LOGD("LOGIN successful, validating client");
-           pss->valid = true;
-           } else {
-           LOGD("LOGIN failed, invalidating client");
-           pss->valid = false;
-           }
-           */
-        pss->valid = true;
-
-        if (agent->initialized()) {
-            pss->need_init = true;
-            ecore_pipe_write(agent->get_message_pipe(), MESSAGE_LEFT, strlen(MESSAGE_LEFT));
-        }
-    }
-
-    /* Ignore valid check since the magic key is not used anymore */
-    if (!pss->valid) pss->valid = true;
-
-    if (pss->valid) {
-        pthread_mutex_lock(&g_ws_server_mutex);
-        std::queue<ISE_MESSAGE>& messages = agent->get_recv_message_queue();
-        messages.push(message);
-        pthread_mutex_unlock(&g_ws_server_mutex);
-
-        ecore_pipe_write(agent->get_message_pipe(), RECVED_MESSAGE, strlen(RECVED_MESSAGE));
-
-        /* If we received reply message, let's send signal to wake up our main thread */
-        if (message.type.compare(ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_REPLY]) == 0) {
-            pthread_mutex_lock(&g_ws_query_mutex);
-            pthread_cond_signal(&g_ws_query_condition);
-            pthread_mutex_unlock(&g_ws_query_mutex);
-        }
-    } else {
-        LOGD("Ignoring data received since client is not valid %d", pss->session_id);
-    }
-
-    return ECORE_CALLBACK_CANCEL;
-}
-
-static int callback_keyboard(struct lws *wsi,
-        enum lws_callback_reasons reason,
-        void *user, void *in, size_t len)
-{
-    static int last_session_id = 0;
-    const int bufsize = 512;
-    int n = 0;
-    unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + bufsize +
-                          LWS_SEND_BUFFER_POST_PADDING];
-    unsigned char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
-    struct per_session_data__keyboard *pss = (struct per_session_data__keyboard *)user;
-    CWebHelperAgentWebSocket *agent = CWebHelperAgentWebSocket::get_current_instance();
-
-    switch (reason) {
-    case LWS_CALLBACK_ESTABLISHED:
-        pss->session_id = ++last_session_id;
-        LOGD("LWS_CALLBACK_ESTABLISHED : %p %d", g_ws_server_context, pss->session_id);
-        pss->valid = false;
-        pss->need_init = false;
-        pss->initialized = false;
-        if (g_ws_server_context) {
-            ecore_pipe_write(agent->get_message_pipe(), MESSAGE_LEFT, strlen(MESSAGE_LEFT));
-        }
-        break;
-
-    case LWS_CALLBACK_CLOSED:
-        LOGD("LWS_CALLBACK_CLOSED : %d", pss->session_id);
-        break;
-
-    case LWS_CALLBACK_SERVER_WRITEABLE:
-        if (agent) {
-            /* Ignore valid check since the magic key is not used anymore */
-            if (!pss->valid) pss->valid = true;
-
-            /* We allow data tranmission only if this client is guaranteed to be valid */
-            if (pss->valid) {
-                pthread_mutex_lock(&g_ws_server_mutex);
-                std::queue<ISE_MESSAGE>& messages = agent->get_send_message_queue();
-
-                if (pss->need_init && !pss->initialized) {
-                    ISE_MESSAGE message;
-                    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
-                    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_INIT];
-                    std::string str = CISEMessageSerializer::serialize(message);
-                    SECURE_LOGD("SEND_WEBSOCKET_MESSAGE : %d %s", pss->session_id, str.c_str());
-                    n = snprintf((char *)p, bufsize, "%s", str.c_str());
-                    /* too small for partial */
-                    n = lws_write(wsi, p, n, LWS_WRITE_TEXT);
-                    pss->need_init = false;
-                    pss->initialized = true;
-                } else {
-                    /* One write allowed per one writable callback */
-                    if (messages.size() > 0) {
-                        ISE_MESSAGE &message = messages.front();
-                        bool drop = false;
-                        if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_INIT]) == 0) {
-                            if (pss->initialized) {
-                                drop = true;
-                            } else {
-                                pss->initialized = true;
-                            }
-                        }
-                        if (!drop) {
-                            std::string str = CISEMessageSerializer::serialize(message);
-                            SECURE_LOGD("SEND_WEBSOCKET_MESSAGE : %d %s", pss->session_id, str.c_str());
-                            n = snprintf((char *)p, bufsize, "%s", str.c_str());
-                            /* too small for partial */
-                            n = lws_write(wsi, p, n, LWS_WRITE_TEXT);
-                        }
-                        messages.pop();
-                    }
-                }
-                if (messages.size() > 0) {
-                    ecore_pipe_write(agent->get_message_pipe(), MESSAGE_LEFT, strlen(MESSAGE_LEFT));
-                }
-                pthread_mutex_unlock(&g_ws_server_mutex);
-
-                if (n < 0) {
-                    LOGE("ERROR %d writing to di socket %d", n, pss->session_id);
-                }
-
-                if (messages.size() > 0) {
-                    lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-                }
-            } else {
-                LOGD("Rejecting data transmission since client is not valid : %d", pss->session_id);
-            }
-        }
-        break;
-
-    case LWS_CALLBACK_RECEIVE:
-        if (in) {
-            if (g_flush_server_recv_buffer_timer) {
-                ecore_thread_main_loop_begin();
-                ecore_timer_del(g_flush_server_recv_buffer_timer);
-                g_flush_server_recv_buffer_timer = NULL;
-                ecore_thread_main_loop_end();
-            }
-
-            std::string str = std::string((const char *)in, len);
-            if (CISEMessageSerializer::valid(str)) {
-                LOGD("A valid new message received, flush previous buffer");
-                flush_server_recv_buffer_func((void*)pss);
-            }
-
-            pthread_mutex_lock(&g_ws_server_mutex);
-            server_recv_buffer += str;
-            SECURE_LOGD("RECEIVE callback : [%zu] [%s], [%s]", len, str.c_str(), server_recv_buffer.c_str());
-            pthread_mutex_unlock(&g_ws_server_mutex);
-
-            ecore_thread_main_loop_begin();
-            g_flush_server_recv_buffer_timer = ecore_timer_add(0.05, flush_server_recv_buffer_func, (void*)pss);
-            SECURE_LOGD("flush timer registered : %p", g_flush_server_recv_buffer_timer);
-            ecore_thread_main_loop_end();
-        }
-
-        break;
-    default:
-        break;
-    }
-
-    return 0;
-}
-
-void *process_ws_server(void *data)
-{
-    while (!force_exit && !g_ws_server_exit) {
-        struct timeval tv;
-        gettimeofday(&tv, NULL);
-
-        if (g_ws_server_context) {
-            lws_service(g_ws_server_context, 50);
-        } else {
-            LOGD("WARNING : g_ws_server_context is NULL");
-        }
-    }
-    LOGD("process_ws_server exits now");
-    return NULL;
-}
-
-void log_func(int level, const char *line)
-{
-    if (line) {
-        LOGD("LEVEL : %d , %s", level, line);
-    }
-}
-
-CWebHelperAgentWebSocket::CWebHelperAgentWebSocket()
-{
-    if (m_current_instance != NULL) {
-        LOGD("WARNING : m_current_instance is NOT NULL");
-    }
-    m_current_instance = this;
-    m_message_pipe = NULL;
-    m_initialized = false;
-}
-
-CWebHelperAgentWebSocket::~CWebHelperAgentWebSocket()
-{
-    if (m_current_instance == this) {
-        m_current_instance = NULL;
-    }
-
-    if (m_message_pipe) {
-        ecore_pipe_del(m_message_pipe);
-        m_message_pipe = NULL;
-    }
-}
-
-static void message_pipe_handler(void *data, void *buffer, unsigned int nbyte)
-{
-    if (buffer) {
-        if (strncmp((const char*)buffer, RECVED_MESSAGE, strlen(RECVED_MESSAGE)) == 0) {
-            CWebHelperAgentWebSocket *agent = CWebHelperAgentWebSocket::get_current_instance();
-            if (agent) {
-                agent->process_recved_messages();
-            }
-        } else {
-            if (g_ws_server_context) {
-                lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-            } else {
-                LOGD("WARNING : g_ws_server_context is NULL");
-            }
-        }
-    }
-}
-
-bool CWebHelperAgentWebSocket::init()
-{
-    bool ret = true;
-
-    struct lws_context_creation_info info;
-
-    memset(&info, 0, sizeof info);
-    info.port = WEBSOCKET_PORT;
-
-    int log_level = LLL_ERR | LLL_WARN | LLL_DEBUG;
-    lws_set_log_level(log_level, log_func);
-
-    info.iface = NULL;
-    info.protocols = protocols;
-    info.extensions = NULL;
-    info.ssl_cert_filepath = NULL;
-    info.ssl_private_key_filepath = NULL;
-    info.gid = -1;
-    info.uid = -1;
-    info.options = 0;
-
-    ecore_init();
-
-    /* The WebSocket server is running on a separate thread, and let the thread send a message
-        through this pipe to guarantee thread safety */
-    m_message_pipe = ecore_pipe_add(message_pipe_handler, NULL);
-
-    /* Let's retry creating server context for a certain number of times */
-    const int max_retry_num = 30;
-    int retry_num = 0;
-
-    do {
-        g_ws_server_context = lws_create_context(&info);
-        LOGD("libwebsocket context : %p", g_ws_server_context);
-        usleep(100 * 1000);
-    } while (g_ws_server_context == NULL && retry_num++ < max_retry_num);
-
-    pthread_mutex_init(&g_ws_server_mutex, NULL);
-
-    pthread_mutex_init(&g_ws_query_mutex, NULL);
-    pthread_cond_init(&g_ws_query_condition, NULL);
-
-    m_initialized = true;
-
-    return ret;
-}
-
-bool CWebHelperAgentWebSocket::exit()
-{
-    if (g_flush_server_recv_buffer_timer)
-        ecore_timer_del(g_flush_server_recv_buffer_timer);
-    g_flush_server_recv_buffer_timer = NULL;
-
-    on_exit();
-
-    g_ws_server_exit = true;
-    if (g_ws_server_context) {
-        lws_cancel_service(g_ws_server_context);
-    }
-
-    if (m_message_pipe) {
-        ecore_pipe_del(m_message_pipe);
-        m_message_pipe = NULL;
-    }
-
-    if (g_ws_server_thread) {
-        pthread_join(g_ws_server_thread, NULL);
-    }
-
-    pthread_cond_destroy(&g_ws_query_condition);
-    pthread_mutex_destroy(&g_ws_query_mutex);
-
-    pthread_mutex_destroy(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_context_destroy(g_ws_server_context);
-        g_ws_server_context = NULL;
-    }
-
-    ecore_shutdown();
-
-    return true;
-}
-
-bool CWebHelperAgentWebSocket::run()
-{
-    if (!m_initialized) {
-        LOGE("Not initialized");
-        return false;
-    }
-
-    bool ret = false;
-    if (g_ws_server_context) {
-        if (pthread_create(&g_ws_server_thread, NULL, &process_ws_server, NULL) != 0) {
-            g_ws_server_thread = (pthread_t)NULL;
-            ret = false;
-
-            on_init();
-
-            test_client_connection();
-        }
-    } else {
-        LOGE("Failed creating server context : %p", g_ws_server_context);
-        ret = false;
-    }
-    return ret;
-}
-
-void CWebHelperAgentWebSocket::signal(int sig)
-{
-    force_exit = 1;
-}
-
-template<class T>
-std::string to_string(T i)
-{
-    std::stringstream ss;
-    std::string s;
-    ss << i;
-    s = ss.str();
-
-    return s;
-}
-
-void CWebHelperAgentWebSocket::on_init()
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_INIT];
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-}
-
-void CWebHelperAgentWebSocket::on_exit()
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_EXIT];
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-}
-
-void CWebHelperAgentWebSocket::on_focus_in(int ic)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_FOCUS_IN];
-    message.values.push_back(to_string(ic));
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-}
-
-void CWebHelperAgentWebSocket::on_focus_out(int ic)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_FOCUS_OUT];
-    message.values.push_back(to_string(ic));
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-}
-
-void CWebHelperAgentWebSocket::on_show(int ic)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SHOW];
-    message.values.push_back(to_string(ic));
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-
-    LOGD("put into send message buffer");
-}
-
-void CWebHelperAgentWebSocket::on_hide(int ic)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_HIDE];
-    message.values.push_back(to_string(ic));
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-}
-
-void CWebHelperAgentWebSocket::on_set_rotation(int degree)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_ROTATION];
-    message.values.push_back(to_string(degree));
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-}
-
-void CWebHelperAgentWebSocket::on_update_cursor_position(int ic, int cursor_pos)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_UPDATE_CURSOR_POSITION];
-    message.values.push_back(to_string(ic));
-    message.values.push_back(to_string(cursor_pos));
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-}
-
-void CWebHelperAgentWebSocket::on_update_surrounding_text(int ic, const char *text, int cursor)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_REPLY];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_UPDATE_SURROUNDING_TEXT];
-    message.values.push_back(to_string(cursor));
-    message.values.push_back(text);
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-}
-
-void CWebHelperAgentWebSocket::on_update_selection(int ic, const char *text)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_REPLY];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_UPDATE_SELECTION];
-    message.values.push_back(text);
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-}
-
-void CWebHelperAgentWebSocket::on_set_language(unsigned int language)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_LANGUAGE];
-
-    bool found = false;
-    for (unsigned int loop = 0;loop < sizeof(ISE_LANGUAGE_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
-        if (language == (unsigned int)ISE_LANGUAGE_TYPES[loop].type_value) {
-            message.values.push_back(ISE_LANGUAGE_TYPES[loop].type_string);
-            found = true;
-        }
-    }
-
-    if (found) {
-        pthread_mutex_lock(&g_ws_server_mutex);
-        m_send_message_queue.push(message);
-        pthread_mutex_unlock(&g_ws_server_mutex);
-
-        if (g_ws_server_context) {
-            lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-        } else {
-            LOGD("WARNING : g_ws_server_context is NULL");
-        }
-    }
-}
-
-void CWebHelperAgentWebSocket::on_set_imdata(char *buf, unsigned int len)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_IMDATA];
-    message.values.push_back(buf);
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-}
-
-void CWebHelperAgentWebSocket::on_get_imdata(char **buf, unsigned int *len)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_QUERY];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_IMDATA];
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-
-    wait_for_reply_message();
-
-    std::vector<std::string> values;
-    /* Check if we received reply for GET_IMDATA message */
-    if (process_recved_messages_until_reply_found(
-        ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_IMDATA], values)) {
-            if (values.size() > 0 && buf && len) {
-                int string_length = values.at(0).length();
-                (*buf) = new char[string_length + 1];
-                if (*buf) {
-                    strncpy(*buf, values.at(0).c_str(), string_length);
-                    /* Make sure this is a null-terminated string */
-                    *(*buf + string_length) = '\0';
-                    *len = string_length;
-                }
-            }
-    } else {
-        LOGD("process_recved_messages_until_reply_found returned FALSE");
-    }
-    /* Now process the rest in the recv buffer */
-    process_recved_messages();
-}
-
-void CWebHelperAgentWebSocket::on_set_return_key_type(unsigned int type)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_RETURN_KEY_TYPE];
-
-    bool found = false;
-    for (unsigned int loop = 0;loop < sizeof(ISE_RETURN_KEY_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
-        if (type == (unsigned int)ISE_RETURN_KEY_TYPES[loop].type_value) {
-            message.values.push_back(ISE_RETURN_KEY_TYPES[loop].type_string);
-            found = true;
-        }
-    }
-
-    if (found) {
-        pthread_mutex_lock(&g_ws_server_mutex);
-        m_send_message_queue.push(message);
-        pthread_mutex_unlock(&g_ws_server_mutex);
-
-        if (g_ws_server_context) {
-            lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-        } else {
-            LOGD("WARNING : g_ws_server_context is NULL");
-        }
-    }
-}
-
-void CWebHelperAgentWebSocket::on_get_return_key_type(unsigned int *type)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_QUERY];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_RETURN_KEY_TYPE];
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-
-    wait_for_reply_message();
-
-    std::vector<std::string> values;
-    /* Check if we received reply for GET_RETURN_KEY_TYPE message */
-    if (process_recved_messages_until_reply_found(
-        ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_RETURN_KEY_TYPE], values)) {
-            if (type) {
-                for (unsigned int loop = 0;loop < sizeof(ISE_RETURN_KEY_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
-                    if (values.at(0).compare(ISE_RETURN_KEY_TYPES[loop].type_string) == 0) {
-                        *type = ISE_RETURN_KEY_TYPES[loop].type_value;
-                    }
-                }
-            }
-    }
-    /* Now process the rest in the recv buffer */
-    process_recved_messages();
-}
-
-void CWebHelperAgentWebSocket::on_set_return_key_disable(unsigned int disabled)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_RETURN_KEY_DISABLE];
-
-    bool found = false;
-    for (unsigned int loop = 0;loop < sizeof(ISE_TRUEFALSE_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
-        if (disabled == (unsigned int)ISE_TRUEFALSE_TYPES[loop].type_value) {
-            message.values.push_back(ISE_TRUEFALSE_TYPES[loop].type_string);
-            found = true;
-        }
-    }
-
-    if (found) {
-        pthread_mutex_lock(&g_ws_server_mutex);
-        m_send_message_queue.push(message);
-        pthread_mutex_unlock(&g_ws_server_mutex);
-
-        if (g_ws_server_context) {
-            lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-        } else {
-            LOGD("WARNING : g_ws_server_context is NULL");
-        }
-    }
-}
-
-void CWebHelperAgentWebSocket::on_get_return_key_disable(unsigned int *disabled)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_QUERY];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_RETURN_KEY_DISABLE];
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-
-    wait_for_reply_message();
-
-    std::vector<std::string> values;
-    /* Check if we received reply for GET_RETURN_KEY_DISABLE message */
-    if (process_recved_messages_until_reply_found(
-        ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_RETURN_KEY_DISABLE], values)) {
-            if (disabled) {
-                for (unsigned int loop = 0;loop < sizeof(ISE_TRUEFALSE_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
-                    if (values.at(0).compare(ISE_TRUEFALSE_TYPES[loop].type_string) == 0) {
-                        *disabled = ISE_TRUEFALSE_TYPES[loop].type_value;
-                    }
-                }
-            }
-    }
-    /* Now process the rest in the recv buffer */
-    process_recved_messages();
-}
-
-void CWebHelperAgentWebSocket::on_set_layout(unsigned int layout)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_LAYOUT];
-
-    bool found = false;
-    for (unsigned int loop = 0;loop < sizeof(ISE_LAYOUT_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
-        if (layout == (unsigned int)ISE_LAYOUT_TYPES[loop].type_value) {
-            message.values.push_back(ISE_LAYOUT_TYPES[loop].type_string);
-            found = true;
-        }
-    }
-
-    if (found) {
-        pthread_mutex_lock(&g_ws_server_mutex);
-        m_send_message_queue.push(message);
-        pthread_mutex_unlock(&g_ws_server_mutex);
-
-        if (g_ws_server_context) {
-            lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-        } else {
-            LOGD("WARNING : g_ws_server_context is NULL");
-        }
-    }
-}
-
-void CWebHelperAgentWebSocket::on_get_layout(unsigned int *layout)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_QUERY];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_LAYOUT];
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-
-    wait_for_reply_message();
-
-    std::vector<std::string> values;
-    /* Check if we received reply for GET_LAYOUT message */
-    if (process_recved_messages_until_reply_found(
-        ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_LAYOUT], values)) {
-            if (layout) {
-                for (unsigned int loop = 0;loop < sizeof(ISE_LAYOUT_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
-                    if (values.at(0).compare(ISE_LAYOUT_TYPES[loop].type_string) == 0) {
-                        *layout = ISE_LAYOUT_TYPES[loop].type_value;
-                    }
-                }
-            }
-    }
-    /* Now process the rest in the recv buffer */
-    process_recved_messages();
-}
-
-void CWebHelperAgentWebSocket::on_reset_input_context(int ic)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_RESET_INPUT_CONTEXT];
-    message.values.push_back(to_string(ic));
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-}
-
-void CWebHelperAgentWebSocket::on_process_key_event(unsigned int code, unsigned int mask, unsigned int layout, unsigned int *ret)
-{
-    ISE_MESSAGE message;
-    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_QUERY];
-    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_PROCESS_KEY_EVENT];
-    message.values.push_back(to_string(code));
-    message.values.push_back(to_string(mask));
-    message.values.push_back(to_string(layout));
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-    m_send_message_queue.push(message);
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    if (g_ws_server_context) {
-        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-    } else {
-        LOGD("WARNING : g_ws_server_context is NULL");
-    }
-
-    wait_for_reply_message();
-
-    std::vector<std::string> values;
-    /* Check if we received reply for PROCESS_KEY_EVENT message */
-    if (process_recved_messages_until_reply_found(
-        ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_PROCESS_KEY_EVENT], values)) {
-            if (ret) {
-                for (unsigned int loop = 0;loop < sizeof(ISE_TRUEFALSE_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
-                    if (values.at(0).compare(ISE_TRUEFALSE_TYPES[loop].type_string) == 0) {
-                        *ret = ISE_TRUEFALSE_TYPES[loop].type_value;
-                    }
-                }
-            }
-    }
-    /* Now process the rest in the recv buffer */
-    process_recved_messages();
-}
-
-CWebHelperAgentWebSocket* CWebHelperAgentWebSocket::get_current_instance()
-{
-    return m_current_instance;
-}
-
-std::queue<ISE_MESSAGE>& CWebHelperAgentWebSocket::get_send_message_queue()
-{
-    return m_send_message_queue;
-}
-
-std::queue<ISE_MESSAGE>& CWebHelperAgentWebSocket::get_recv_message_queue()
-{
-    return m_recv_message_queue;
-}
-
-Ecore_Pipe* CWebHelperAgentWebSocket::get_message_pipe()
-{
-    return m_message_pipe;
-}
-
-void CWebHelperAgentWebSocket::wait_for_reply_message()
-{
-    /* Let's wait for at most REPLY_TIMEOUT */
-    struct timeval now;
-    struct timespec timeout;
-    gettimeofday(&now, NULL);
-    timeout.tv_sec = now.tv_sec + REPLY_TIMEOUT.tv_sec;
-    timeout.tv_nsec = (now.tv_usec + REPLY_TIMEOUT.tv_usec) * 1000;
-    pthread_mutex_lock(&g_ws_query_mutex);
-    pthread_cond_timedwait(&g_ws_query_condition, &g_ws_query_mutex, &timeout);
-    pthread_mutex_unlock(&g_ws_query_mutex);
-}
-
-void CWebHelperAgentWebSocket::process_recved_messages()
-{
-    pthread_mutex_lock(&g_ws_server_mutex);
-
-    while (m_recv_message_queue.size() > 0) {
-        ISE_MESSAGE &message = m_recv_message_queue.front();
-
-        handle_recved_message(message);
-
-        m_recv_message_queue.pop();
-    }
-
-    pthread_mutex_unlock(&g_ws_server_mutex);
-}
-
-bool CWebHelperAgentWebSocket::process_recved_messages_until_reply_found(std::string command, std::vector<std::string> &values)
-{
-    bool ret = false;
-
-    pthread_mutex_lock(&g_ws_server_mutex);
-
-    while (ret == false && m_recv_message_queue.size() > 0) {
-        ISE_MESSAGE &message = m_recv_message_queue.front();
-
-        if (message.command.compare(command) == 0 &&
-            message.type.compare(ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_REPLY]) == 0) {
-            ret = true;
-            values = message.values;
-        }
-        handle_recved_message(message);
-
-        m_recv_message_queue.pop();
-    }
-
-    pthread_mutex_unlock(&g_ws_server_mutex);
-
-    return ret;
-}
-
-void CWebHelperAgentWebSocket::handle_recved_message(ISE_MESSAGE &message)
-{
-    static bool _key_event_processing = false;
-    if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_LOG]) == 0) {
-        std::string str = "";
-        for (unsigned int loop = 0;loop < message.values.size();loop++) {
-            str += message.values.at(loop).c_str();
-            if (loop < message.values.size() - 1) {
-                str += " ";
-            }
-        }
-        log(str.c_str());
-    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_COMMIT_STRING]) == 0) {
-        std::string str = "";
-        for (unsigned int loop = 0;loop < message.values.size();loop++) {
-            str += message.values.at(loop).c_str();
-            if (loop < message.values.size() - 1) {
-                str += " ";
-            }
-        }
-        if (_key_event_processing) {
-            struct timeval tv;
-            tv.tv_sec = 0;
-            tv.tv_usec = 50000;
-            select(0, NULL, NULL, NULL, &tv);
-            _key_event_processing = false;
-        }
-        commit_string(str.c_str());
-    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_UPDATE_PREEDIT_STRING]) == 0) {
-        std::string str = "";
-        for (unsigned int loop = 0;loop < message.values.size();loop++) {
-            str += message.values.at(loop).c_str();
-            if (loop < message.values.size() - 1) {
-                str += " ";
-            }
-        }
-        update_preedit_string(str.c_str());
-    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SEND_KEY_EVENT]) == 0) {
-        if (message.values.size() == 1) {
-            forward_key_event(atoi(message.values.at(0).c_str()));
-            _key_event_processing = true;
-        }
-    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_KEYBOARD_SIZES]) == 0) {
-        LOGD("ISE_MESSAGE_COMMAND_SET_KEYBOARD_SIZES");
-        int portrait_width, portrait_height;
-        int landscape_width, landscape_height;
-
-        if (message.values.size() == 4 || message.values.size() == 2) {
-            portrait_width = atoi(message.values.at(0).c_str());
-            portrait_height = atoi(message.values.at(1).c_str());
-            if (message.values.size() == 2) {
-                landscape_width = portrait_width;
-                landscape_height = portrait_height;
-            } else {
-                landscape_width = atoi(message.values.at(2).c_str());
-                landscape_height = atoi(message.values.at(3).c_str());
-            }
-
-            LOGD("ISE_MESSAGE_COMMAND_SET_KEYBOARD_SIZES : %d %d %d %d",
-                portrait_width, portrait_height, landscape_width, landscape_height);
-
-#ifdef WAYLAND
-            /* Since the full screen IME makes the client application fully obscured,
-             * when it hides the client receives resume command and try to show IME again.
-             * So here we are adjusting the height value when the requested keyboard size
-             * is the same with the screen size, as a workaround */
-            int scr_w = 0, scr_h = 0;
-            ecore_wl2_sync();
-            Ecore_Wl2_Display *ewd = NULL;
-            if ((ewd = ecore_wl2_connected_display_get(NULL))) {
-                ecore_wl2_display_screen_size_get(ewd, &scr_w, &scr_h);
-
-                if (scr_w == portrait_width && scr_h == portrait_height) {
-                    portrait_height -= 1;
-                }
-                if (scr_h == landscape_width && scr_w == landscape_height) {
-                    landscape_height -= 1;
-                }
-            }
-#endif
-
-            set_keyboard_sizes(
-                portrait_width, portrait_height, landscape_width, landscape_height);
-        }
-    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_SELECTION]) == 0) {
-        LOGD("ISE_MESSAGE_COMMAND_SET_SELECTION");
-        if (message.values.size() == 2) {
-            LOGD("ISE_MESSAGE_COMMAND_SET_SELECTION : %d %d",
-                atoi(message.values.at(0).c_str()), atoi(message.values.at(1).c_str()));
-            set_selection(
-                atoi(message.values.at(0).c_str()), atoi(message.values.at(1).c_str()));
-        }
-    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_SELECTION]) == 0) {
-        if (message.values.size() == 0) {
-            get_selection();
-        }
-    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_SURROUNDING_TEXT]) == 0) {
-        LOGD("ISE_MESSAGE_COMMAND_GET_SURROUNDING_TEXT");
-        if (message.values.size() == 2) {
-            LOGD("ISE_MESSAGE_COMMAND_GET_SURROUNDING_TEXT : %d %d",
-                atoi(message.values.at(0).c_str()), atoi(message.values.at(1).c_str()));
-            get_surrounding_text(
-                atoi(message.values.at(0).c_str()), atoi(message.values.at(1).c_str()));
-        }
-    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_DELETE_SURROUNDING_TEXT]) == 0) {
-        LOGD("ISE_MESSAGE_COMMAND_DELETE_SURROUNDING_TEXT");
-        if (message.values.size() == 2) {
-            LOGD("ISE_MESSAGE_COMMAND_DELETE_SURROUNDING_TEXT : %d %d",
-                atoi(message.values.at(0).c_str()), atoi(message.values.at(1).c_str()));
-            delete_surrounding_text(
-                atoi(message.values.at(0).c_str()), atoi(message.values.at(1).c_str()));
-        }
-    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_LOGIN]) == 0) {
-        if (g_ws_server_context) {
-            lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
-        } else {
-            LOGD("WARNING : g_ws_server_context is NULL");
-        }
-    }
-}
diff --git a/src/legacy_support/websocket.h b/src/legacy_support/websocket.h
deleted file mode 100644 (file)
index 0be56b4..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright (c) 2012 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef _WEB_HELPER_AGENT_WEBSOCKET_H_
-#define _WEB_HELPER_AGENT_WEBSOCKET_H_
-
-#include "web_helper_agent.h"
-
-#include <queue>
-
-#include <Ecore.h>
-#include <Eina.h>
-#include <Ecore_IMF.h>
-
-/* Wait for at most 1 second */
-const struct timeval REPLY_TIMEOUT = {1, 0};
-
-typedef enum {
-    ISE_MESSAGE_TYPE_PLAIN,
-    ISE_MESSAGE_TYPE_QUERY,
-    ISE_MESSAGE_TYPE_REPLY,
-
-    ISE_MESSAGE_TYPES_NUM,
-} ISE_MESSAGE_TYPES;
-
-const std::string ISE_MESSAGE_TYPE_STRINGS[] = {
-    "plain", // ISE_MESSAGE_TYPE_PLAIN,
-    "query", // ISE_MESSAGE_TYPE_QUERY
-    "reply", // ISE_MESSAGE_TYPE_REPLY
-};
-
-typedef enum {
-    ISE_MESSAGE_COMMAND_INIT,
-    ISE_MESSAGE_COMMAND_EXIT,
-
-    ISE_MESSAGE_COMMAND_FOCUS_IN,
-    ISE_MESSAGE_COMMAND_FOCUS_OUT,
-    ISE_MESSAGE_COMMAND_SHOW,
-    ISE_MESSAGE_COMMAND_HIDE,
-    ISE_MESSAGE_COMMAND_SET_ROTATION,
-    ISE_MESSAGE_COMMAND_UPDATE_CURSOR_POSITION,
-    ISE_MESSAGE_COMMAND_UPDATE_SURROUNDING_TEXT,
-    ISE_MESSAGE_COMMAND_UPDATE_SELECTION,
-    ISE_MESSAGE_COMMAND_SET_LANGUAGE,
-    ISE_MESSAGE_COMMAND_SET_IMDATA,
-    ISE_MESSAGE_COMMAND_GET_IMDATA,
-    ISE_MESSAGE_COMMAND_SET_RETURN_KEY_TYPE,
-    ISE_MESSAGE_COMMAND_GET_RETURN_KEY_TYPE,
-    ISE_MESSAGE_COMMAND_SET_RETURN_KEY_DISABLE,
-    ISE_MESSAGE_COMMAND_GET_RETURN_KEY_DISABLE,
-    ISE_MESSAGE_COMMAND_SET_LAYOUT,
-    ISE_MESSAGE_COMMAND_GET_LAYOUT,
-    ISE_MESSAGE_COMMAND_RESET_INPUT_CONTEXT,
-    ISE_MESSAGE_COMMAND_PROCESS_KEY_EVENT,
-
-    ISE_MESSAGE_COMMAND_LOG,
-    ISE_MESSAGE_COMMAND_COMMIT_STRING,
-    ISE_MESSAGE_COMMAND_UPDATE_PREEDIT_STRING,
-    ISE_MESSAGE_COMMAND_SEND_KEY_EVENT,
-    ISE_MESSAGE_COMMAND_FORWARD_KEY_EVENT,
-    ISE_MESSAGE_COMMAND_SET_KEYBOARD_SIZES,
-    ISE_MESSAGE_COMMAND_SET_SELECTION,
-    ISE_MESSAGE_COMMAND_GET_SELECTION,
-    ISE_MESSAGE_COMMAND_GET_SURROUNDING_TEXT,
-    ISE_MESSAGE_COMMAND_DELETE_SURROUNDING_TEXT,
-    ISE_MESSAGE_COMMAND_LOGIN,
-
-    ISE_MESSAGE_COMMANDS_NUM,
-} ISE_MESSAGE_COMMANDS;
-
-const std::string ISE_MESSAGE_COMMAND_STRINGS[] = {
-    "init", // ISE_MESSAGE_COMMAND_INIT,
-    "exit", // ISE_MESSAGE_COMMAND_EXIT,
-
-    "focus_in", // ISE_MESSAGE_COMMAND_FOCUS_IN,
-    "focus_out", // ISE_MESSAGE_COMMAND_FOCUS_OUT,
-    "show", // ISE_MESSAGE_COMMAND_SHOW,
-    "hide", // ISE_MESSAGE_COMMAND_HIDE,
-    "set_rotation", // ISE_MESSAGE_COMMAND_SET_ROTATION,
-    "update_cursor_position", // ISE_MESSAGE_COMMAND_UPDATE_CURSOR_POSITION,
-    "update_surrounding_text", // ISE_MESSAGE_COMMAND_UPDATE_SURROUNDING_TEXT,
-    "update_selection", // ISE_MESSAGE_COMMAND_UPDATE_SELECTION
-    "set_language", // ISE_MESSAGE_COMMAND_SET_LANGUAGE,
-    "set_imdata", // ISE_MESSAGE_COMMAND_SET_IMDATA,
-    "get_imdata", // ISE_MESSAGE_COMMAND_GET_IMDATA,
-    "set_return_key_type", // ISE_MESSAGE_COMMAND_SET_RETURN_KEY_TYPE,
-    "get_return_key_type", // ISE_MESSAGE_COMMAND_GET_RETURN_KEY_TYPE,
-    "set_return_key_disable", // ISE_MESSAGE_COMMAND_SET_RETURN_KEY_DISABLE,
-    "get_return_key_disable", // ISE_MESSAGE_COMMAND_GET_RETURN_KEY_DISABLE,
-    "set_layout", // ISE_MESSAGE_COMMAND_SET_LAYOUT,
-    "get_layout", // ISE_MESSAGE_COMMAND_GET_LAYOUT,
-    "reset_input_context", // ISE_MESSAGE_COMMAND_RESET_INPUT_CONTEXT,
-    "process_key_event", // ISE_MESSAGE_COMMAND_PROCESS_KEY_EVENT,
-
-    "log", // ISE_MESSAGE_COMMAND_LOG,
-    "commit_string", // ISE_MESSAGE_COMMAND_COMMIT_STRING,
-    "update_preedit_string", // ISE_MESSAGE_COMMAND_UPDATE_PREEDIT_STRING,
-    "send_key_event", // ISE_MESSAGE_COMMAND_SEND_KEY_EVENT,
-    "forward_key_event", // ISE_MESSAGE_COMMAND_FORWARD_KEY_EVENT,
-    "set_keyboard_sizes", // ISE_MESSAGE_COMMAND_SET_KEYBOARD_SIZES,
-    "set_selection", // ISE_MESSAGE_COMMAND_SET_SELECTION,
-    "get_selection", // ISE_MESSAGE_COMMAND_GET_SELECTION,
-    "get_surrounding_text", // ISE_MESSAGE_COMMAND_GET_SURROUNDING_TEXT,
-    "delete_surrounding_text", // ISE_MESSAGE_COMMAND_DELETE_SURROUNDING_TEXT,
-    "login", // ISE_MESSAGE_COMMAND_LOGIN,
-};
-
-typedef struct {
-    std::string type;
-    std::string command;
-    std::vector<std::string> values;
-} ISE_MESSAGE;
-
-typedef struct {
-    int type_value;
-    std::string type_string;
-} ISE_TYPE_VALUE_STRING;
-
-const ISE_TYPE_VALUE_STRING ISE_RETURN_KEY_TYPES[] = {
-    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT, "default"},
-    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DONE, "done"},
-    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_GO, "go"},
-    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_JOIN, "join"},
-    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_LOGIN, "login"},
-    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_NEXT, "next"},
-    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEARCH, "search"},
-    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEND, "send"},
-    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SIGNIN, "signin"},
-};
-
-const ISE_TYPE_VALUE_STRING ISE_LAYOUT_TYPES[] = {
-    {ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL, "normal"},
-    {ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBER, "number"},
-    {ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL, "email"},
-    {ECORE_IMF_INPUT_PANEL_LAYOUT_URL, "url"},
-    {ECORE_IMF_INPUT_PANEL_LAYOUT_PHONENUMBER, "phonenumber"},
-    {ECORE_IMF_INPUT_PANEL_LAYOUT_IP, "ip"},
-    {ECORE_IMF_INPUT_PANEL_LAYOUT_MONTH, "month"},
-    {ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY, "numberonly"},
-    {ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD, "password"},
-    {ECORE_IMF_INPUT_PANEL_LAYOUT_DATETIME, "datetime"},
-};
-
-const ISE_TYPE_VALUE_STRING ISE_LANGUAGE_TYPES[] = {
-    {ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC, "automatic"},
-    {ECORE_IMF_INPUT_PANEL_LANG_ALPHABET, "alphabet"},
-};
-
-/* FIXME : Should consider the case if the boolean value does not match with EINA_TRUE or EINA_FALSE */
-const ISE_TYPE_VALUE_STRING ISE_TRUEFALSE_TYPES[] = {
-    {EINA_FALSE, "false"},
-    {EINA_TRUE, "true"},
-};
-
-class CISEMessageSerializer
-{
-protected:
-    /* FIXME : Temporary solution for distinguish commands and values */
-    static const char MESSAGE_DELIMETER = ' ';
-
-public:
-    static std::string serialize(ISE_MESSAGE message) {
-        std::string ret;
-        ret += message.type;
-        ret += MESSAGE_DELIMETER;
-        ret += message.command;
-        for (unsigned int loop = 0;loop < message.values.size();loop++) {
-            ret += MESSAGE_DELIMETER;
-            ret += message.values.at(loop);
-        }
-        return ret;
-    }
-
-    static ISE_MESSAGE deserialize(std::string message) {
-        ISE_MESSAGE ret;
-        std::vector<std::string> vec = CStringTokenizer::split(message, MESSAGE_DELIMETER);
-        if (vec.size() > 1) {
-            ret.type = vec.at(0);
-            vec.erase(vec.begin());
-            ret.command = vec.at(0);
-            vec.erase(vec.begin());
-            ret.values = vec;
-        }
-        return ret;
-    }
-
-    static bool valid(std::string str)
-    {
-        int loop;
-
-        bool valid_type = false;
-        bool valid_command = false;
-
-        ISE_MESSAGE message;
-        message = deserialize(str);
-
-        for (loop = 0;!valid_type && loop < ISE_MESSAGE_TYPES_NUM;loop++) {
-            if (message.type.compare(ISE_MESSAGE_TYPE_STRINGS[loop]) == 0) {
-                valid_type = true;
-            }
-        }
-        for (loop = 0;!valid_command && loop < ISE_MESSAGE_COMMANDS_NUM;loop++) {
-            if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[loop]) == 0) {
-                valid_command = true;
-            }
-        }
-
-        return (valid_type && valid_command);
-    }
-};
-
-class CWebHelperAgentWebSocket : public CWebHelperAgent {
-public:
-    CWebHelperAgentWebSocket();
-    virtual ~CWebHelperAgentWebSocket();
-
-    bool init();
-    bool exit();
-
-    bool run();
-
-    bool initialized() { return m_initialized; }
-
-    void signal(int sig);
-
-    void on_init();
-    void on_exit();
-
-    void on_focus_in(int ic);
-    void on_focus_out(int ic);
-
-    void on_show(int ic);
-    void on_hide(int ic);
-
-    void on_set_rotation(int degree);
-
-    void on_update_cursor_position(int ic, int cursor_pos);
-    void on_update_surrounding_text(int ic, const char *text, int cursor);
-    void on_update_selection(int ic, const char *text);
-
-    void on_set_language(unsigned int language);
-
-    void on_set_imdata(char *buf, unsigned int len);
-    void on_get_imdata(char **buf, unsigned int *len);
-
-    void on_set_return_key_type(unsigned int type);
-    void on_get_return_key_type(unsigned int *type);
-
-    void on_set_return_key_disable(unsigned int disabled);
-    void on_get_return_key_disable(unsigned int *disabled);
-
-    void on_set_layout(unsigned int layout);
-    void on_get_layout(unsigned int *layout);
-
-    void on_reset_input_context(int ic);
-
-    void on_process_key_event(unsigned int code, unsigned int mask, unsigned int layout, unsigned int *ret);
-
-    std::queue<ISE_MESSAGE>& get_send_message_queue();
-    std::queue<ISE_MESSAGE>& get_recv_message_queue();
-    Ecore_Pipe* get_message_pipe();
-
-    void wait_for_reply_message();
-
-    void process_recved_messages();
-    bool process_recved_messages_until_reply_found(std::string command, std::vector<std::string> &values);
-    void handle_recved_message(ISE_MESSAGE &message);
-
-    static CWebHelperAgentWebSocket* get_current_instance();
-protected:
-    static CWebHelperAgentWebSocket *m_current_instance;
-
-    std::queue<ISE_MESSAGE> m_send_message_queue;
-    std::queue<ISE_MESSAGE> m_recv_message_queue;
-
-    Ecore_Pipe *m_message_pipe;
-
-    bool m_initialized;
-};
-
-#endif // _WEB_HELPER_AGENT_WEBSOCKET_H_
index d00c7ce48d6dec11e47ff995235c1ada617fabe4..74b13e3d27e73c14c186f585fa41336c564e113b 100644 (file)
@@ -21,7 +21,7 @@
 #include <dlog.h>
 
 #ifdef WEBSOCKET
-#include "legacy_support/websocket.h"
+#include "websocket.h"
 extern CWebHelperAgentWebSocket g_websocket;
 #endif
 
index 82d03af0315217de58b507a9e5d6dfff3fb897d0..73585900051f2896ae8206dca6d7745d0a8b3680 100644 (file)
@@ -23,7 +23,7 @@
 #include <Ecore.h>
 
 #ifdef WEBSOCKET
-#include "legacy_support/websocket.h"
+#include "websocket.h"
 #endif
 
 //SCL_BEGIN_DECLS
diff --git a/src/web_helper_agent.cpp b/src/web_helper_agent.cpp
new file mode 100644 (file)
index 0000000..1d3cfc5
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2012 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <dlog.h>
+
+#include "web_helper_agent.h"
+
+#include "websocket.h"
+#include "sclcoreimpl.h"
+
+using namespace scl;
+
+typedef struct {
+    int major_version;
+    WEB_HELPER_AGENT_TYPE agent_type;
+} WEB_HELPER_AGENT_TYPES_FOR_VERSIONS;
+
+static WEB_HELPER_AGENT_TYPES_FOR_VERSIONS web_helper_agent_types_for_versions[] = {
+    {1, WEB_HELPER_AGENT_WEBSOCKET}, /* Major version 1 indicates that it uses websocket for communication */
+};
+
+static int WEB_HELPER_AGENT_TYPES_FOR_VERSIONS_NUM = \
+    sizeof(web_helper_agent_types_for_versions) / sizeof(WEB_HELPER_AGENT_TYPES_FOR_VERSIONS);
+
+WEB_HELPER_AGENT_TYPE CWebHelperAgent::get_web_helper_agent_type_from_major_version(int version)
+{
+    for (int loop = 0;loop < WEB_HELPER_AGENT_TYPES_FOR_VERSIONS_NUM;loop++) {
+        if (web_helper_agent_types_for_versions[loop].major_version == version) {
+            return web_helper_agent_types_for_versions[loop].agent_type;
+        }
+    }
+    return WEB_HELPER_AGENT_UNKNOWN;
+}
+
+CWebHelperAgent* CWebHelperAgent::create_web_helper_agent(WEB_HELPER_AGENT_TYPE type)
+{
+    CWebHelperAgent *ret = NULL;
+    if (type == WEB_HELPER_AGENT_WEBSOCKET) {
+        ret = new CWebHelperAgentWebSocket;
+    }
+    return ret;
+}
+
+void CWebHelperAgent::destroy_web_helper_agent(CWebHelperAgent* agent)
+{
+    if (agent) delete agent;
+}
+
+CWebHelperAgent::CWebHelperAgent()
+{
+}
+
+CWebHelperAgent::~CWebHelperAgent()
+{
+}
+
+bool CWebHelperAgent::init()
+{
+    return true;
+}
+
+bool CWebHelperAgent::exit()
+{
+    return true;
+}
+
+void CWebHelperAgent::signal(int sig)
+{
+}
+
+void CWebHelperAgent::log(const char *str)
+{
+    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
+    if (impl) {
+        //impl->logise_log(str);
+    }
+}
+
+void CWebHelperAgent::commit_string(const char *str)
+{
+    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
+    if (impl) {
+        impl->commit_string(-1, "", str);
+    }
+}
+
+void CWebHelperAgent::update_preedit_string(const char *str)
+{
+    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
+    if (impl) {
+        impl->update_preedit_string(-1, "", str);
+    }
+}
+
+void CWebHelperAgent::send_key_event(unsigned int key, unsigned int key_mask)
+{
+    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
+    if (impl) {
+        impl->send_key_event(-1, "", key, key_mask);
+    }
+}
+
+void CWebHelperAgent::forward_key_event(unsigned int key)
+{
+    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
+    if (impl) {
+        impl->forward_key_event(-1, "", key, scim::SCIM_KEY_NullMask);
+    }
+}
+
+void CWebHelperAgent::set_keyboard_sizes(int portrait_width, int portrait_height, int landscape_width, int landscape_height)
+{
+    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
+    if (impl) {
+        SclSize portrait, landscape;
+        portrait.width = portrait_width;
+        portrait.height = portrait_height;
+        landscape.width = landscape_width;
+        landscape.height = landscape_height;
+        impl->set_keyboard_size_hints(portrait, landscape);
+    }
+}
+
+void CWebHelperAgent::set_selection(int start_index, int end_index)
+{
+    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
+    if (impl) {
+        impl->set_selection(start_index, end_index);
+    }
+}
+
+void CWebHelperAgent::get_selection()
+{
+    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
+    if (impl) {
+        //impl->get_selection(-1, "", );
+    }
+}
+
+void CWebHelperAgent::get_surrounding_text(int maxlen_before, int maxlen_after)
+{
+    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
+    if (impl) {
+        impl->get_surrounding_text("", maxlen_before, maxlen_after);
+    }
+}
+
+void CWebHelperAgent::delete_surrounding_text(int offset, int len)
+{
+    CSCLCoreImpl *impl = CSCLCoreImpl::get_instance();
+    if (impl) {
+        impl->delete_surrounding_text(offset, len);
+    }
+}
+
+std::string CMagicKeyManager::get_magic_key()
+{
+    static std::string current_magic_key;
+
+    /* If we don't have magic key generated yet */
+    if (current_magic_key.length() != MAGIC_KEY_LENGTH) {
+        char magic_key[MAGIC_KEY_LENGTH + 1];
+        /* We are going to generate a magic key that contains ascii characters in the range of '0' to 'z' */
+        const char magic_key_range_lower = '0';
+        const char magic_key_range_upper = 'Z';
+
+        unsigned int seed = time(NULL);
+        for (int loop = 0;loop < MAGIC_KEY_LENGTH;loop++) {
+            magic_key[loop] = (rand_r(&seed) % (magic_key_range_upper - magic_key_range_lower)) + magic_key_range_lower;
+        }
+        magic_key[MAGIC_KEY_LENGTH] = '\0';
+
+        current_magic_key = magic_key;
+    }
+
+    return current_magic_key;
+}
diff --git a/src/web_helper_agent.h b/src/web_helper_agent.h
new file mode 100644 (file)
index 0000000..c05c572
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2012 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _WEB_HELPER_AGENT_H_
+#define _WEB_HELPER_AGENT_H_
+
+#define MAGIC_KEY_LENGTH 32
+#define VERSION_DELIMITER '.'
+#define VERSION_TOKEN_NUM 2 // We are expecting 2 version tokens : MAJOR and MINOR
+
+#include <string>
+#include <sstream>
+#include <vector>
+
+class CStringTokenizer
+{
+public:
+    static std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
+        unsigned int loop = 0;
+        unsigned int start = 0;
+        for (loop = 0;loop < s.length();loop++) {
+            if (s.at(loop) == delim) {
+                std::string item = s.substr(start, loop - start);
+                elems.push_back(item);
+                start = loop + 1;
+            }
+        }
+        std::string item = s.substr(start, loop - start);
+        elems.push_back(item);
+        return elems;
+    }
+
+    static std::vector<std::string> split(const std::string &s, char delim) {
+        std::vector<std::string> elems;
+        split(s, delim, elems);
+        return elems;
+    }
+};
+
+typedef enum {
+    WEB_HELPER_AGENT_UNKNOWN,
+    WEB_HELPER_AGENT_WEBSOCKET,
+    WEB_HELPER_AGENT_DIRECT,
+} WEB_HELPER_AGENT_TYPE;
+
+class CMagicKeyManager
+{
+public:
+    static std::string get_magic_key();
+};
+
+class CWebHelperAgent
+{
+public:
+    CWebHelperAgent();
+    virtual ~CWebHelperAgent();
+
+    virtual bool init();
+    virtual bool exit();
+
+    virtual bool run() { return false; }
+    virtual void signal(int sig);
+
+    virtual void on_init() {}
+    virtual void on_exit() {}
+
+    virtual void on_focus_in(int ic) {}
+    virtual void on_focus_out(int ic) {}
+
+    virtual void on_show(int ic) {}
+    virtual void on_hide(int ic) {}
+
+    virtual void on_set_rotation(int degree) {}
+
+    virtual void on_update_cursor_position(int ic, int cursor_pos) {}
+    virtual void on_update_surrounding_text(int ic, const char *text, int cursor) {}
+    virtual void on_update_selection(int ic, const char *text) {}
+
+    virtual void on_set_language(unsigned int language) {}
+
+    virtual void on_set_imdata(char *buf, unsigned int len) {}
+    virtual void on_get_imdata(char **buf, unsigned int *len) {}
+
+    virtual void on_set_return_key_type(unsigned int type) {}
+    virtual void on_get_return_key_type(unsigned int *type) {}
+
+    virtual void on_set_return_key_disable(unsigned int disabled) {}
+    virtual void on_get_return_key_disable(unsigned int *disabled) {}
+
+    virtual void on_set_layout(unsigned int layout) {}
+    virtual void on_get_layout(unsigned int *layout) {}
+
+    virtual void on_reset_input_context(int ic) {}
+
+    virtual void on_process_key_event(unsigned int code, unsigned int mask, unsigned int layout, unsigned int *ret) {}
+
+
+    virtual void log(const char *str);
+    virtual void commit_string(const char *str);
+    virtual void update_preedit_string(const char *str);
+    virtual void send_key_event(unsigned int key, unsigned int key_mask);
+    virtual void forward_key_event(unsigned int key);
+    virtual void set_keyboard_sizes(int portrait_width, int portrait_height, int landscape_width, int landscape_height);
+    virtual void set_selection(int start_index, int end_index);
+    virtual void get_selection();
+    virtual void get_surrounding_text(int maxlen_before, int maxlen_after);
+    virtual void delete_surrounding_text(int offset, int len);
+
+public:
+    static WEB_HELPER_AGENT_TYPE get_web_helper_agent_type_from_major_version(int version);
+    static CWebHelperAgent* create_web_helper_agent(WEB_HELPER_AGENT_TYPE type);
+    static void destroy_web_helper_agent(CWebHelperAgent* agent);
+};
+
+#endif // _WEB_HELPER_AGENT_H_
diff --git a/src/websocket.cpp b/src/websocket.cpp
new file mode 100644 (file)
index 0000000..2ae2565
--- /dev/null
@@ -0,0 +1,1252 @@
+/*
+ * Copyright (c) 2012 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <Ecore.h>
+#include <Ecore_IMF.h>
+#include <dlog.h>
+
+#include "websocket.h"
+
+#include <syslog.h>
+#include <signal.h>
+
+#include <libwebsockets.h>
+
+#ifdef WAYLAND
+#define EFL_BETA_API_SUPPORT
+#include <Ecore_Wl2.h>
+#endif
+
+#define WEBSOCKET_PORT 7681
+
+#define RECVED_MESSAGE "recved"
+#define MESSAGE_LEFT "left"
+
+pthread_t g_ws_server_thread = (pthread_t)NULL;
+pthread_mutex_t g_ws_server_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+pthread_cond_t g_ws_query_condition = PTHREAD_COND_INITIALIZER;
+pthread_mutex_t g_ws_query_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+bool g_ws_server_exit = false;
+struct lws_context *g_ws_server_context = NULL;
+
+CWebHelperAgentWebSocket* CWebHelperAgentWebSocket::m_current_instance = NULL;
+
+int force_exit = 0;
+
+enum protocols {
+    /* always first */
+    PROTOCOL_HTTP = 0,
+
+    PROTOCOL_KEYBOARD,
+
+    /* always last */
+    MAX_PROTOCOL_COUNT
+};
+
+struct per_session_data__http {
+    int fd;
+};
+
+static int callback_http(struct lws *wsi,
+        enum lws_callback_reasons reason,
+        void *user, void *in, size_t len)
+{
+    return 0;
+}
+
+struct per_session_data__keyboard {
+    int session_id;
+    int valid;
+    int need_init;
+    int initialized;
+};
+
+static int callback_keyboard(struct lws *wsi,
+        enum lws_callback_reasons reason,
+        void *user, void *in, size_t len);
+
+static struct lws_protocols protocols[] = {
+    {
+        "http-only",
+        callback_http,
+        sizeof(struct per_session_data__http),
+        0,
+    },
+    {
+        "keyboard-protocol",
+        callback_keyboard,
+        sizeof(struct per_session_data__keyboard),
+        32,
+    },
+    { NULL, NULL, 0, 0 }
+};
+
+
+static int callback_client(struct lws *wsi,
+    enum lws_callback_reasons reason,
+    void *user, void *in, size_t len)
+{
+    switch (reason) {
+    case LWS_CALLBACK_CLIENT_ESTABLISHED:
+        LOGD("[ClientTest] Connection established");
+        break;
+
+    case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
+        LOGD("[ClientTest] Connection error");
+        break;
+
+    case LWS_CALLBACK_CLOSED:
+        LOGD("[ClientTest] Connection closed");
+        break;
+
+    default:
+        break;
+    }
+
+    return 0;
+}
+
+int test_client_connection(void)
+{
+    struct lws_context *context = NULL;
+    struct lws_context_creation_info context_info;
+    struct lws_client_connect_info connect_info;
+    struct lws *wsi = NULL;
+
+    memset(&context_info, 0, sizeof context_info);
+    memset(&connect_info, 0, sizeof(connect_info));
+
+    const int protocols_num = sizeof(protocols) / sizeof(lws_protocols);
+    static struct lws_protocols client_protocols[protocols_num];
+
+    memcpy(&client_protocols, protocols, sizeof(protocols));
+    for (int loop = 0; loop < protocols_num - 1; loop++) {
+        client_protocols[loop].callback = callback_client;
+    }
+
+    context_info.port = CONTEXT_PORT_NO_LISTEN;
+    context_info.protocols = protocols;
+    context_info.gid = -1;
+    context_info.uid = -1;
+
+    context = lws_create_context(&context_info);
+    LOGD("[ClientTest] create_context : %p", context);
+    if (context == NULL) {
+        return -1;
+    }
+
+    connect_info.address = "localhost";
+    connect_info.port = WEBSOCKET_PORT;
+    connect_info.path = "/";
+    connect_info.context = context;
+    connect_info.ssl_connection = 0;
+    connect_info.host = connect_info.address;
+    connect_info.origin = connect_info.address;
+    connect_info.ietf_version_or_minus_one = -1;
+    connect_info.protocol = "keyboard-protocol";
+
+    wsi = lws_client_connect_via_info(&connect_info);
+    LOGD("[ClientTest] wsi created : %p", wsi);
+
+    if (wsi) {
+        lws_service(context, 50);
+    }
+
+    lws_context_destroy(context);
+
+    return 0;
+}
+
+static Ecore_Timer *g_flush_server_recv_buffer_timer = NULL;
+static std::string server_recv_buffer;
+static Eina_Bool flush_server_recv_buffer_func(void *user)
+{
+    LOGD("flushing recv buffer");
+    CWebHelperAgentWebSocket *agent = CWebHelperAgentWebSocket::get_current_instance();
+    struct per_session_data__keyboard *pss = (struct per_session_data__keyboard *)user;
+
+    if (g_flush_server_recv_buffer_timer)
+        ecore_timer_del(g_flush_server_recv_buffer_timer);
+    g_flush_server_recv_buffer_timer = NULL;
+
+    if (!agent || !pss) return ECORE_CALLBACK_CANCEL;
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    ISE_MESSAGE message = CISEMessageSerializer::deserialize(server_recv_buffer);
+    server_recv_buffer.clear();
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_LOGIN]) == 0) {
+        /*
+           if (message.values.at(0).compare(CMagicKeyManager::get_magic_key()) == 0) {
+           LOGD("LOGIN successful, validating client");
+           pss->valid = true;
+           } else {
+           LOGD("LOGIN failed, invalidating client");
+           pss->valid = false;
+           }
+           */
+        pss->valid = true;
+
+        if (agent->initialized()) {
+            pss->need_init = true;
+            ecore_pipe_write(agent->get_message_pipe(), MESSAGE_LEFT, strlen(MESSAGE_LEFT));
+        }
+    }
+
+    /* Ignore valid check since the magic key is not used anymore */
+    if (!pss->valid) pss->valid = true;
+
+    if (pss->valid) {
+        pthread_mutex_lock(&g_ws_server_mutex);
+        std::queue<ISE_MESSAGE>& messages = agent->get_recv_message_queue();
+        messages.push(message);
+        pthread_mutex_unlock(&g_ws_server_mutex);
+
+        ecore_pipe_write(agent->get_message_pipe(), RECVED_MESSAGE, strlen(RECVED_MESSAGE));
+
+        /* If we received reply message, let's send signal to wake up our main thread */
+        if (message.type.compare(ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_REPLY]) == 0) {
+            pthread_mutex_lock(&g_ws_query_mutex);
+            pthread_cond_signal(&g_ws_query_condition);
+            pthread_mutex_unlock(&g_ws_query_mutex);
+        }
+    } else {
+        LOGD("Ignoring data received since client is not valid %d", pss->session_id);
+    }
+
+    return ECORE_CALLBACK_CANCEL;
+}
+
+static int callback_keyboard(struct lws *wsi,
+        enum lws_callback_reasons reason,
+        void *user, void *in, size_t len)
+{
+    static int last_session_id = 0;
+    const int bufsize = 512;
+    int n = 0;
+    unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + bufsize +
+                          LWS_SEND_BUFFER_POST_PADDING];
+    unsigned char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
+    struct per_session_data__keyboard *pss = (struct per_session_data__keyboard *)user;
+    CWebHelperAgentWebSocket *agent = CWebHelperAgentWebSocket::get_current_instance();
+
+    switch (reason) {
+    case LWS_CALLBACK_ESTABLISHED:
+        pss->session_id = ++last_session_id;
+        LOGD("LWS_CALLBACK_ESTABLISHED : %p %d", g_ws_server_context, pss->session_id);
+        pss->valid = false;
+        pss->need_init = false;
+        pss->initialized = false;
+        if (g_ws_server_context) {
+            ecore_pipe_write(agent->get_message_pipe(), MESSAGE_LEFT, strlen(MESSAGE_LEFT));
+        }
+        break;
+
+    case LWS_CALLBACK_CLOSED:
+        LOGD("LWS_CALLBACK_CLOSED : %d", pss->session_id);
+        break;
+
+    case LWS_CALLBACK_SERVER_WRITEABLE:
+        if (agent) {
+            /* Ignore valid check since the magic key is not used anymore */
+            if (!pss->valid) pss->valid = true;
+
+            /* We allow data tranmission only if this client is guaranteed to be valid */
+            if (pss->valid) {
+                pthread_mutex_lock(&g_ws_server_mutex);
+                std::queue<ISE_MESSAGE>& messages = agent->get_send_message_queue();
+
+                if (pss->need_init && !pss->initialized) {
+                    ISE_MESSAGE message;
+                    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
+                    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_INIT];
+                    std::string str = CISEMessageSerializer::serialize(message);
+                    SECURE_LOGD("SEND_WEBSOCKET_MESSAGE : %d %s", pss->session_id, str.c_str());
+                    n = snprintf((char *)p, bufsize, "%s", str.c_str());
+                    /* too small for partial */
+                    n = lws_write(wsi, p, n, LWS_WRITE_TEXT);
+                    pss->need_init = false;
+                    pss->initialized = true;
+                } else {
+                    /* One write allowed per one writable callback */
+                    if (messages.size() > 0) {
+                        ISE_MESSAGE &message = messages.front();
+                        bool drop = false;
+                        if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_INIT]) == 0) {
+                            if (pss->initialized) {
+                                drop = true;
+                            } else {
+                                pss->initialized = true;
+                            }
+                        }
+                        if (!drop) {
+                            std::string str = CISEMessageSerializer::serialize(message);
+                            SECURE_LOGD("SEND_WEBSOCKET_MESSAGE : %d %s", pss->session_id, str.c_str());
+                            n = snprintf((char *)p, bufsize, "%s", str.c_str());
+                            /* too small for partial */
+                            n = lws_write(wsi, p, n, LWS_WRITE_TEXT);
+                        }
+                        messages.pop();
+                    }
+                }
+                if (messages.size() > 0) {
+                    ecore_pipe_write(agent->get_message_pipe(), MESSAGE_LEFT, strlen(MESSAGE_LEFT));
+                }
+                pthread_mutex_unlock(&g_ws_server_mutex);
+
+                if (n < 0) {
+                    LOGE("ERROR %d writing to di socket %d", n, pss->session_id);
+                }
+
+                if (messages.size() > 0) {
+                    lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+                }
+            } else {
+                LOGD("Rejecting data transmission since client is not valid : %d", pss->session_id);
+            }
+        }
+        break;
+
+    case LWS_CALLBACK_RECEIVE:
+        if (in) {
+            if (g_flush_server_recv_buffer_timer) {
+                ecore_thread_main_loop_begin();
+                ecore_timer_del(g_flush_server_recv_buffer_timer);
+                g_flush_server_recv_buffer_timer = NULL;
+                ecore_thread_main_loop_end();
+            }
+
+            std::string str = std::string((const char *)in, len);
+            if (CISEMessageSerializer::valid(str)) {
+                LOGD("A valid new message received, flush previous buffer");
+                flush_server_recv_buffer_func((void*)pss);
+            }
+
+            pthread_mutex_lock(&g_ws_server_mutex);
+            server_recv_buffer += str;
+            SECURE_LOGD("RECEIVE callback : [%zu] [%s], [%s]", len, str.c_str(), server_recv_buffer.c_str());
+            pthread_mutex_unlock(&g_ws_server_mutex);
+
+            ecore_thread_main_loop_begin();
+            g_flush_server_recv_buffer_timer = ecore_timer_add(0.05, flush_server_recv_buffer_func, (void*)pss);
+            SECURE_LOGD("flush timer registered : %p", g_flush_server_recv_buffer_timer);
+            ecore_thread_main_loop_end();
+        }
+
+        break;
+    default:
+        break;
+    }
+
+    return 0;
+}
+
+void *process_ws_server(void *data)
+{
+    while (!force_exit && !g_ws_server_exit) {
+        struct timeval tv;
+        gettimeofday(&tv, NULL);
+
+        if (g_ws_server_context) {
+            lws_service(g_ws_server_context, 50);
+        } else {
+            LOGD("WARNING : g_ws_server_context is NULL");
+        }
+    }
+    LOGD("process_ws_server exits now");
+    return NULL;
+}
+
+void log_func(int level, const char *line)
+{
+    if (line) {
+        LOGD("LEVEL : %d , %s", level, line);
+    }
+}
+
+CWebHelperAgentWebSocket::CWebHelperAgentWebSocket()
+{
+    if (m_current_instance != NULL) {
+        LOGD("WARNING : m_current_instance is NOT NULL");
+    }
+    m_current_instance = this;
+    m_message_pipe = NULL;
+    m_initialized = false;
+}
+
+CWebHelperAgentWebSocket::~CWebHelperAgentWebSocket()
+{
+    if (m_current_instance == this) {
+        m_current_instance = NULL;
+    }
+
+    if (m_message_pipe) {
+        ecore_pipe_del(m_message_pipe);
+        m_message_pipe = NULL;
+    }
+}
+
+static void message_pipe_handler(void *data, void *buffer, unsigned int nbyte)
+{
+    if (buffer) {
+        if (strncmp((const char*)buffer, RECVED_MESSAGE, strlen(RECVED_MESSAGE)) == 0) {
+            CWebHelperAgentWebSocket *agent = CWebHelperAgentWebSocket::get_current_instance();
+            if (agent) {
+                agent->process_recved_messages();
+            }
+        } else {
+            if (g_ws_server_context) {
+                lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+            } else {
+                LOGD("WARNING : g_ws_server_context is NULL");
+            }
+        }
+    }
+}
+
+bool CWebHelperAgentWebSocket::init()
+{
+    bool ret = true;
+
+    struct lws_context_creation_info info;
+
+    memset(&info, 0, sizeof info);
+    info.port = WEBSOCKET_PORT;
+
+    int log_level = LLL_ERR | LLL_WARN | LLL_DEBUG;
+    lws_set_log_level(log_level, log_func);
+
+    info.iface = NULL;
+    info.protocols = protocols;
+    info.extensions = NULL;
+    info.ssl_cert_filepath = NULL;
+    info.ssl_private_key_filepath = NULL;
+    info.gid = -1;
+    info.uid = -1;
+    info.options = 0;
+
+    ecore_init();
+
+    /* The WebSocket server is running on a separate thread, and let the thread send a message
+        through this pipe to guarantee thread safety */
+    m_message_pipe = ecore_pipe_add(message_pipe_handler, NULL);
+
+    /* Let's retry creating server context for a certain number of times */
+    const int max_retry_num = 30;
+    int retry_num = 0;
+
+    do {
+        g_ws_server_context = lws_create_context(&info);
+        LOGD("libwebsocket context : %p", g_ws_server_context);
+        usleep(100 * 1000);
+    } while (g_ws_server_context == NULL && retry_num++ < max_retry_num);
+
+    pthread_mutex_init(&g_ws_server_mutex, NULL);
+
+    pthread_mutex_init(&g_ws_query_mutex, NULL);
+    pthread_cond_init(&g_ws_query_condition, NULL);
+
+    m_initialized = true;
+
+    return ret;
+}
+
+bool CWebHelperAgentWebSocket::exit()
+{
+    if (g_flush_server_recv_buffer_timer)
+        ecore_timer_del(g_flush_server_recv_buffer_timer);
+    g_flush_server_recv_buffer_timer = NULL;
+
+    on_exit();
+
+    g_ws_server_exit = true;
+    if (g_ws_server_context) {
+        lws_cancel_service(g_ws_server_context);
+    }
+
+    if (m_message_pipe) {
+        ecore_pipe_del(m_message_pipe);
+        m_message_pipe = NULL;
+    }
+
+    if (g_ws_server_thread) {
+        pthread_join(g_ws_server_thread, NULL);
+    }
+
+    pthread_cond_destroy(&g_ws_query_condition);
+    pthread_mutex_destroy(&g_ws_query_mutex);
+
+    pthread_mutex_destroy(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_context_destroy(g_ws_server_context);
+        g_ws_server_context = NULL;
+    }
+
+    ecore_shutdown();
+
+    return true;
+}
+
+bool CWebHelperAgentWebSocket::run()
+{
+    if (!m_initialized) {
+        LOGE("Not initialized");
+        return false;
+    }
+
+    bool ret = false;
+    if (g_ws_server_context) {
+        if (pthread_create(&g_ws_server_thread, NULL, &process_ws_server, NULL) != 0) {
+            g_ws_server_thread = (pthread_t)NULL;
+            ret = false;
+
+            on_init();
+
+            test_client_connection();
+        }
+    } else {
+        LOGE("Failed creating server context : %p", g_ws_server_context);
+        ret = false;
+    }
+    return ret;
+}
+
+void CWebHelperAgentWebSocket::signal(int sig)
+{
+    force_exit = 1;
+}
+
+template<class T>
+std::string to_string(T i)
+{
+    std::stringstream ss;
+    std::string s;
+    ss << i;
+    s = ss.str();
+
+    return s;
+}
+
+void CWebHelperAgentWebSocket::on_init()
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_INIT];
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+}
+
+void CWebHelperAgentWebSocket::on_exit()
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_EXIT];
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+}
+
+void CWebHelperAgentWebSocket::on_focus_in(int ic)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_FOCUS_IN];
+    message.values.push_back(to_string(ic));
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+}
+
+void CWebHelperAgentWebSocket::on_focus_out(int ic)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_FOCUS_OUT];
+    message.values.push_back(to_string(ic));
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+}
+
+void CWebHelperAgentWebSocket::on_show(int ic)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SHOW];
+    message.values.push_back(to_string(ic));
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+
+    LOGD("put into send message buffer");
+}
+
+void CWebHelperAgentWebSocket::on_hide(int ic)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_HIDE];
+    message.values.push_back(to_string(ic));
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+}
+
+void CWebHelperAgentWebSocket::on_set_rotation(int degree)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_ROTATION];
+    message.values.push_back(to_string(degree));
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+}
+
+void CWebHelperAgentWebSocket::on_update_cursor_position(int ic, int cursor_pos)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_UPDATE_CURSOR_POSITION];
+    message.values.push_back(to_string(ic));
+    message.values.push_back(to_string(cursor_pos));
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+}
+
+void CWebHelperAgentWebSocket::on_update_surrounding_text(int ic, const char *text, int cursor)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_REPLY];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_UPDATE_SURROUNDING_TEXT];
+    message.values.push_back(to_string(cursor));
+    message.values.push_back(text);
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+}
+
+void CWebHelperAgentWebSocket::on_update_selection(int ic, const char *text)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_REPLY];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_UPDATE_SELECTION];
+    message.values.push_back(text);
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+}
+
+void CWebHelperAgentWebSocket::on_set_language(unsigned int language)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_LANGUAGE];
+
+    bool found = false;
+    for (unsigned int loop = 0;loop < sizeof(ISE_LANGUAGE_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
+        if (language == (unsigned int)ISE_LANGUAGE_TYPES[loop].type_value) {
+            message.values.push_back(ISE_LANGUAGE_TYPES[loop].type_string);
+            found = true;
+        }
+    }
+
+    if (found) {
+        pthread_mutex_lock(&g_ws_server_mutex);
+        m_send_message_queue.push(message);
+        pthread_mutex_unlock(&g_ws_server_mutex);
+
+        if (g_ws_server_context) {
+            lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+        } else {
+            LOGD("WARNING : g_ws_server_context is NULL");
+        }
+    }
+}
+
+void CWebHelperAgentWebSocket::on_set_imdata(char *buf, unsigned int len)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_IMDATA];
+    message.values.push_back(buf);
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+}
+
+void CWebHelperAgentWebSocket::on_get_imdata(char **buf, unsigned int *len)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_QUERY];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_IMDATA];
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+
+    wait_for_reply_message();
+
+    std::vector<std::string> values;
+    /* Check if we received reply for GET_IMDATA message */
+    if (process_recved_messages_until_reply_found(
+        ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_IMDATA], values)) {
+            if (values.size() > 0 && buf && len) {
+                int string_length = values.at(0).length();
+                (*buf) = new char[string_length + 1];
+                if (*buf) {
+                    strncpy(*buf, values.at(0).c_str(), string_length);
+                    /* Make sure this is a null-terminated string */
+                    *(*buf + string_length) = '\0';
+                    *len = string_length;
+                }
+            }
+    } else {
+        LOGD("process_recved_messages_until_reply_found returned FALSE");
+    }
+    /* Now process the rest in the recv buffer */
+    process_recved_messages();
+}
+
+void CWebHelperAgentWebSocket::on_set_return_key_type(unsigned int type)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_RETURN_KEY_TYPE];
+
+    bool found = false;
+    for (unsigned int loop = 0;loop < sizeof(ISE_RETURN_KEY_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
+        if (type == (unsigned int)ISE_RETURN_KEY_TYPES[loop].type_value) {
+            message.values.push_back(ISE_RETURN_KEY_TYPES[loop].type_string);
+            found = true;
+        }
+    }
+
+    if (found) {
+        pthread_mutex_lock(&g_ws_server_mutex);
+        m_send_message_queue.push(message);
+        pthread_mutex_unlock(&g_ws_server_mutex);
+
+        if (g_ws_server_context) {
+            lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+        } else {
+            LOGD("WARNING : g_ws_server_context is NULL");
+        }
+    }
+}
+
+void CWebHelperAgentWebSocket::on_get_return_key_type(unsigned int *type)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_QUERY];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_RETURN_KEY_TYPE];
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+
+    wait_for_reply_message();
+
+    std::vector<std::string> values;
+    /* Check if we received reply for GET_RETURN_KEY_TYPE message */
+    if (process_recved_messages_until_reply_found(
+        ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_RETURN_KEY_TYPE], values)) {
+            if (type) {
+                for (unsigned int loop = 0;loop < sizeof(ISE_RETURN_KEY_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
+                    if (values.at(0).compare(ISE_RETURN_KEY_TYPES[loop].type_string) == 0) {
+                        *type = ISE_RETURN_KEY_TYPES[loop].type_value;
+                    }
+                }
+            }
+    }
+    /* Now process the rest in the recv buffer */
+    process_recved_messages();
+}
+
+void CWebHelperAgentWebSocket::on_set_return_key_disable(unsigned int disabled)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_RETURN_KEY_DISABLE];
+
+    bool found = false;
+    for (unsigned int loop = 0;loop < sizeof(ISE_TRUEFALSE_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
+        if (disabled == (unsigned int)ISE_TRUEFALSE_TYPES[loop].type_value) {
+            message.values.push_back(ISE_TRUEFALSE_TYPES[loop].type_string);
+            found = true;
+        }
+    }
+
+    if (found) {
+        pthread_mutex_lock(&g_ws_server_mutex);
+        m_send_message_queue.push(message);
+        pthread_mutex_unlock(&g_ws_server_mutex);
+
+        if (g_ws_server_context) {
+            lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+        } else {
+            LOGD("WARNING : g_ws_server_context is NULL");
+        }
+    }
+}
+
+void CWebHelperAgentWebSocket::on_get_return_key_disable(unsigned int *disabled)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_QUERY];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_RETURN_KEY_DISABLE];
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+
+    wait_for_reply_message();
+
+    std::vector<std::string> values;
+    /* Check if we received reply for GET_RETURN_KEY_DISABLE message */
+    if (process_recved_messages_until_reply_found(
+        ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_RETURN_KEY_DISABLE], values)) {
+            if (disabled) {
+                for (unsigned int loop = 0;loop < sizeof(ISE_TRUEFALSE_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
+                    if (values.at(0).compare(ISE_TRUEFALSE_TYPES[loop].type_string) == 0) {
+                        *disabled = ISE_TRUEFALSE_TYPES[loop].type_value;
+                    }
+                }
+            }
+    }
+    /* Now process the rest in the recv buffer */
+    process_recved_messages();
+}
+
+void CWebHelperAgentWebSocket::on_set_layout(unsigned int layout)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_LAYOUT];
+
+    bool found = false;
+    for (unsigned int loop = 0;loop < sizeof(ISE_LAYOUT_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
+        if (layout == (unsigned int)ISE_LAYOUT_TYPES[loop].type_value) {
+            message.values.push_back(ISE_LAYOUT_TYPES[loop].type_string);
+            found = true;
+        }
+    }
+
+    if (found) {
+        pthread_mutex_lock(&g_ws_server_mutex);
+        m_send_message_queue.push(message);
+        pthread_mutex_unlock(&g_ws_server_mutex);
+
+        if (g_ws_server_context) {
+            lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+        } else {
+            LOGD("WARNING : g_ws_server_context is NULL");
+        }
+    }
+}
+
+void CWebHelperAgentWebSocket::on_get_layout(unsigned int *layout)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_QUERY];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_LAYOUT];
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+
+    wait_for_reply_message();
+
+    std::vector<std::string> values;
+    /* Check if we received reply for GET_LAYOUT message */
+    if (process_recved_messages_until_reply_found(
+        ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_LAYOUT], values)) {
+            if (layout) {
+                for (unsigned int loop = 0;loop < sizeof(ISE_LAYOUT_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
+                    if (values.at(0).compare(ISE_LAYOUT_TYPES[loop].type_string) == 0) {
+                        *layout = ISE_LAYOUT_TYPES[loop].type_value;
+                    }
+                }
+            }
+    }
+    /* Now process the rest in the recv buffer */
+    process_recved_messages();
+}
+
+void CWebHelperAgentWebSocket::on_reset_input_context(int ic)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_PLAIN];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_RESET_INPUT_CONTEXT];
+    message.values.push_back(to_string(ic));
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+}
+
+void CWebHelperAgentWebSocket::on_process_key_event(unsigned int code, unsigned int mask, unsigned int layout, unsigned int *ret)
+{
+    ISE_MESSAGE message;
+    message.type = ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_QUERY];
+    message.command = ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_PROCESS_KEY_EVENT];
+    message.values.push_back(to_string(code));
+    message.values.push_back(to_string(mask));
+    message.values.push_back(to_string(layout));
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+    m_send_message_queue.push(message);
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    if (g_ws_server_context) {
+        lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+    } else {
+        LOGD("WARNING : g_ws_server_context is NULL");
+    }
+
+    wait_for_reply_message();
+
+    std::vector<std::string> values;
+    /* Check if we received reply for PROCESS_KEY_EVENT message */
+    if (process_recved_messages_until_reply_found(
+        ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_PROCESS_KEY_EVENT], values)) {
+            if (ret) {
+                for (unsigned int loop = 0;loop < sizeof(ISE_TRUEFALSE_TYPES) / sizeof(ISE_TYPE_VALUE_STRING);loop++) {
+                    if (values.at(0).compare(ISE_TRUEFALSE_TYPES[loop].type_string) == 0) {
+                        *ret = ISE_TRUEFALSE_TYPES[loop].type_value;
+                    }
+                }
+            }
+    }
+    /* Now process the rest in the recv buffer */
+    process_recved_messages();
+}
+
+CWebHelperAgentWebSocket* CWebHelperAgentWebSocket::get_current_instance()
+{
+    return m_current_instance;
+}
+
+std::queue<ISE_MESSAGE>& CWebHelperAgentWebSocket::get_send_message_queue()
+{
+    return m_send_message_queue;
+}
+
+std::queue<ISE_MESSAGE>& CWebHelperAgentWebSocket::get_recv_message_queue()
+{
+    return m_recv_message_queue;
+}
+
+Ecore_Pipe* CWebHelperAgentWebSocket::get_message_pipe()
+{
+    return m_message_pipe;
+}
+
+void CWebHelperAgentWebSocket::wait_for_reply_message()
+{
+    /* Let's wait for at most REPLY_TIMEOUT */
+    struct timeval now;
+    struct timespec timeout;
+    gettimeofday(&now, NULL);
+    timeout.tv_sec = now.tv_sec + REPLY_TIMEOUT.tv_sec;
+    timeout.tv_nsec = (now.tv_usec + REPLY_TIMEOUT.tv_usec) * 1000;
+    pthread_mutex_lock(&g_ws_query_mutex);
+    pthread_cond_timedwait(&g_ws_query_condition, &g_ws_query_mutex, &timeout);
+    pthread_mutex_unlock(&g_ws_query_mutex);
+}
+
+void CWebHelperAgentWebSocket::process_recved_messages()
+{
+    pthread_mutex_lock(&g_ws_server_mutex);
+
+    while (m_recv_message_queue.size() > 0) {
+        ISE_MESSAGE &message = m_recv_message_queue.front();
+
+        handle_recved_message(message);
+
+        m_recv_message_queue.pop();
+    }
+
+    pthread_mutex_unlock(&g_ws_server_mutex);
+}
+
+bool CWebHelperAgentWebSocket::process_recved_messages_until_reply_found(std::string command, std::vector<std::string> &values)
+{
+    bool ret = false;
+
+    pthread_mutex_lock(&g_ws_server_mutex);
+
+    while (ret == false && m_recv_message_queue.size() > 0) {
+        ISE_MESSAGE &message = m_recv_message_queue.front();
+
+        if (message.command.compare(command) == 0 &&
+            message.type.compare(ISE_MESSAGE_TYPE_STRINGS[ISE_MESSAGE_TYPE_REPLY]) == 0) {
+            ret = true;
+            values = message.values;
+        }
+        handle_recved_message(message);
+
+        m_recv_message_queue.pop();
+    }
+
+    pthread_mutex_unlock(&g_ws_server_mutex);
+
+    return ret;
+}
+
+void CWebHelperAgentWebSocket::handle_recved_message(ISE_MESSAGE &message)
+{
+    static bool _key_event_processing = false;
+    if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_LOG]) == 0) {
+        std::string str = "";
+        for (unsigned int loop = 0;loop < message.values.size();loop++) {
+            str += message.values.at(loop).c_str();
+            if (loop < message.values.size() - 1) {
+                str += " ";
+            }
+        }
+        log(str.c_str());
+    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_COMMIT_STRING]) == 0) {
+        std::string str = "";
+        for (unsigned int loop = 0;loop < message.values.size();loop++) {
+            str += message.values.at(loop).c_str();
+            if (loop < message.values.size() - 1) {
+                str += " ";
+            }
+        }
+        if (_key_event_processing) {
+            struct timeval tv;
+            tv.tv_sec = 0;
+            tv.tv_usec = 50000;
+            select(0, NULL, NULL, NULL, &tv);
+            _key_event_processing = false;
+        }
+        commit_string(str.c_str());
+    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_UPDATE_PREEDIT_STRING]) == 0) {
+        std::string str = "";
+        for (unsigned int loop = 0;loop < message.values.size();loop++) {
+            str += message.values.at(loop).c_str();
+            if (loop < message.values.size() - 1) {
+                str += " ";
+            }
+        }
+        update_preedit_string(str.c_str());
+    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SEND_KEY_EVENT]) == 0) {
+        if (message.values.size() == 1) {
+            forward_key_event(atoi(message.values.at(0).c_str()));
+            _key_event_processing = true;
+        }
+    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_KEYBOARD_SIZES]) == 0) {
+        LOGD("ISE_MESSAGE_COMMAND_SET_KEYBOARD_SIZES");
+        int portrait_width, portrait_height;
+        int landscape_width, landscape_height;
+
+        if (message.values.size() == 4 || message.values.size() == 2) {
+            portrait_width = atoi(message.values.at(0).c_str());
+            portrait_height = atoi(message.values.at(1).c_str());
+            if (message.values.size() == 2) {
+                landscape_width = portrait_width;
+                landscape_height = portrait_height;
+            } else {
+                landscape_width = atoi(message.values.at(2).c_str());
+                landscape_height = atoi(message.values.at(3).c_str());
+            }
+
+            LOGD("ISE_MESSAGE_COMMAND_SET_KEYBOARD_SIZES : %d %d %d %d",
+                portrait_width, portrait_height, landscape_width, landscape_height);
+
+#ifdef WAYLAND
+            /* Since the full screen IME makes the client application fully obscured,
+             * when it hides the client receives resume command and try to show IME again.
+             * So here we are adjusting the height value when the requested keyboard size
+             * is the same with the screen size, as a workaround */
+            int scr_w = 0, scr_h = 0;
+            ecore_wl2_sync();
+            Ecore_Wl2_Display *ewd = NULL;
+            if ((ewd = ecore_wl2_connected_display_get(NULL))) {
+                ecore_wl2_display_screen_size_get(ewd, &scr_w, &scr_h);
+
+                if (scr_w == portrait_width && scr_h == portrait_height) {
+                    portrait_height -= 1;
+                }
+                if (scr_h == landscape_width && scr_w == landscape_height) {
+                    landscape_height -= 1;
+                }
+            }
+#endif
+
+            set_keyboard_sizes(
+                portrait_width, portrait_height, landscape_width, landscape_height);
+        }
+    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_SET_SELECTION]) == 0) {
+        LOGD("ISE_MESSAGE_COMMAND_SET_SELECTION");
+        if (message.values.size() == 2) {
+            LOGD("ISE_MESSAGE_COMMAND_SET_SELECTION : %d %d",
+                atoi(message.values.at(0).c_str()), atoi(message.values.at(1).c_str()));
+            set_selection(
+                atoi(message.values.at(0).c_str()), atoi(message.values.at(1).c_str()));
+        }
+    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_SELECTION]) == 0) {
+        if (message.values.size() == 0) {
+            get_selection();
+        }
+    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_GET_SURROUNDING_TEXT]) == 0) {
+        LOGD("ISE_MESSAGE_COMMAND_GET_SURROUNDING_TEXT");
+        if (message.values.size() == 2) {
+            LOGD("ISE_MESSAGE_COMMAND_GET_SURROUNDING_TEXT : %d %d",
+                atoi(message.values.at(0).c_str()), atoi(message.values.at(1).c_str()));
+            get_surrounding_text(
+                atoi(message.values.at(0).c_str()), atoi(message.values.at(1).c_str()));
+        }
+    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_DELETE_SURROUNDING_TEXT]) == 0) {
+        LOGD("ISE_MESSAGE_COMMAND_DELETE_SURROUNDING_TEXT");
+        if (message.values.size() == 2) {
+            LOGD("ISE_MESSAGE_COMMAND_DELETE_SURROUNDING_TEXT : %d %d",
+                atoi(message.values.at(0).c_str()), atoi(message.values.at(1).c_str()));
+            delete_surrounding_text(
+                atoi(message.values.at(0).c_str()), atoi(message.values.at(1).c_str()));
+        }
+    } else if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[ISE_MESSAGE_COMMAND_LOGIN]) == 0) {
+        if (g_ws_server_context) {
+            lws_callback_on_writable_all_protocol(g_ws_server_context, &protocols[PROTOCOL_KEYBOARD]);
+        } else {
+            LOGD("WARNING : g_ws_server_context is NULL");
+        }
+    }
+}
diff --git a/src/websocket.h b/src/websocket.h
new file mode 100644 (file)
index 0000000..0be56b4
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ * Copyright (c) 2012 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _WEB_HELPER_AGENT_WEBSOCKET_H_
+#define _WEB_HELPER_AGENT_WEBSOCKET_H_
+
+#include "web_helper_agent.h"
+
+#include <queue>
+
+#include <Ecore.h>
+#include <Eina.h>
+#include <Ecore_IMF.h>
+
+/* Wait for at most 1 second */
+const struct timeval REPLY_TIMEOUT = {1, 0};
+
+typedef enum {
+    ISE_MESSAGE_TYPE_PLAIN,
+    ISE_MESSAGE_TYPE_QUERY,
+    ISE_MESSAGE_TYPE_REPLY,
+
+    ISE_MESSAGE_TYPES_NUM,
+} ISE_MESSAGE_TYPES;
+
+const std::string ISE_MESSAGE_TYPE_STRINGS[] = {
+    "plain", // ISE_MESSAGE_TYPE_PLAIN,
+    "query", // ISE_MESSAGE_TYPE_QUERY
+    "reply", // ISE_MESSAGE_TYPE_REPLY
+};
+
+typedef enum {
+    ISE_MESSAGE_COMMAND_INIT,
+    ISE_MESSAGE_COMMAND_EXIT,
+
+    ISE_MESSAGE_COMMAND_FOCUS_IN,
+    ISE_MESSAGE_COMMAND_FOCUS_OUT,
+    ISE_MESSAGE_COMMAND_SHOW,
+    ISE_MESSAGE_COMMAND_HIDE,
+    ISE_MESSAGE_COMMAND_SET_ROTATION,
+    ISE_MESSAGE_COMMAND_UPDATE_CURSOR_POSITION,
+    ISE_MESSAGE_COMMAND_UPDATE_SURROUNDING_TEXT,
+    ISE_MESSAGE_COMMAND_UPDATE_SELECTION,
+    ISE_MESSAGE_COMMAND_SET_LANGUAGE,
+    ISE_MESSAGE_COMMAND_SET_IMDATA,
+    ISE_MESSAGE_COMMAND_GET_IMDATA,
+    ISE_MESSAGE_COMMAND_SET_RETURN_KEY_TYPE,
+    ISE_MESSAGE_COMMAND_GET_RETURN_KEY_TYPE,
+    ISE_MESSAGE_COMMAND_SET_RETURN_KEY_DISABLE,
+    ISE_MESSAGE_COMMAND_GET_RETURN_KEY_DISABLE,
+    ISE_MESSAGE_COMMAND_SET_LAYOUT,
+    ISE_MESSAGE_COMMAND_GET_LAYOUT,
+    ISE_MESSAGE_COMMAND_RESET_INPUT_CONTEXT,
+    ISE_MESSAGE_COMMAND_PROCESS_KEY_EVENT,
+
+    ISE_MESSAGE_COMMAND_LOG,
+    ISE_MESSAGE_COMMAND_COMMIT_STRING,
+    ISE_MESSAGE_COMMAND_UPDATE_PREEDIT_STRING,
+    ISE_MESSAGE_COMMAND_SEND_KEY_EVENT,
+    ISE_MESSAGE_COMMAND_FORWARD_KEY_EVENT,
+    ISE_MESSAGE_COMMAND_SET_KEYBOARD_SIZES,
+    ISE_MESSAGE_COMMAND_SET_SELECTION,
+    ISE_MESSAGE_COMMAND_GET_SELECTION,
+    ISE_MESSAGE_COMMAND_GET_SURROUNDING_TEXT,
+    ISE_MESSAGE_COMMAND_DELETE_SURROUNDING_TEXT,
+    ISE_MESSAGE_COMMAND_LOGIN,
+
+    ISE_MESSAGE_COMMANDS_NUM,
+} ISE_MESSAGE_COMMANDS;
+
+const std::string ISE_MESSAGE_COMMAND_STRINGS[] = {
+    "init", // ISE_MESSAGE_COMMAND_INIT,
+    "exit", // ISE_MESSAGE_COMMAND_EXIT,
+
+    "focus_in", // ISE_MESSAGE_COMMAND_FOCUS_IN,
+    "focus_out", // ISE_MESSAGE_COMMAND_FOCUS_OUT,
+    "show", // ISE_MESSAGE_COMMAND_SHOW,
+    "hide", // ISE_MESSAGE_COMMAND_HIDE,
+    "set_rotation", // ISE_MESSAGE_COMMAND_SET_ROTATION,
+    "update_cursor_position", // ISE_MESSAGE_COMMAND_UPDATE_CURSOR_POSITION,
+    "update_surrounding_text", // ISE_MESSAGE_COMMAND_UPDATE_SURROUNDING_TEXT,
+    "update_selection", // ISE_MESSAGE_COMMAND_UPDATE_SELECTION
+    "set_language", // ISE_MESSAGE_COMMAND_SET_LANGUAGE,
+    "set_imdata", // ISE_MESSAGE_COMMAND_SET_IMDATA,
+    "get_imdata", // ISE_MESSAGE_COMMAND_GET_IMDATA,
+    "set_return_key_type", // ISE_MESSAGE_COMMAND_SET_RETURN_KEY_TYPE,
+    "get_return_key_type", // ISE_MESSAGE_COMMAND_GET_RETURN_KEY_TYPE,
+    "set_return_key_disable", // ISE_MESSAGE_COMMAND_SET_RETURN_KEY_DISABLE,
+    "get_return_key_disable", // ISE_MESSAGE_COMMAND_GET_RETURN_KEY_DISABLE,
+    "set_layout", // ISE_MESSAGE_COMMAND_SET_LAYOUT,
+    "get_layout", // ISE_MESSAGE_COMMAND_GET_LAYOUT,
+    "reset_input_context", // ISE_MESSAGE_COMMAND_RESET_INPUT_CONTEXT,
+    "process_key_event", // ISE_MESSAGE_COMMAND_PROCESS_KEY_EVENT,
+
+    "log", // ISE_MESSAGE_COMMAND_LOG,
+    "commit_string", // ISE_MESSAGE_COMMAND_COMMIT_STRING,
+    "update_preedit_string", // ISE_MESSAGE_COMMAND_UPDATE_PREEDIT_STRING,
+    "send_key_event", // ISE_MESSAGE_COMMAND_SEND_KEY_EVENT,
+    "forward_key_event", // ISE_MESSAGE_COMMAND_FORWARD_KEY_EVENT,
+    "set_keyboard_sizes", // ISE_MESSAGE_COMMAND_SET_KEYBOARD_SIZES,
+    "set_selection", // ISE_MESSAGE_COMMAND_SET_SELECTION,
+    "get_selection", // ISE_MESSAGE_COMMAND_GET_SELECTION,
+    "get_surrounding_text", // ISE_MESSAGE_COMMAND_GET_SURROUNDING_TEXT,
+    "delete_surrounding_text", // ISE_MESSAGE_COMMAND_DELETE_SURROUNDING_TEXT,
+    "login", // ISE_MESSAGE_COMMAND_LOGIN,
+};
+
+typedef struct {
+    std::string type;
+    std::string command;
+    std::vector<std::string> values;
+} ISE_MESSAGE;
+
+typedef struct {
+    int type_value;
+    std::string type_string;
+} ISE_TYPE_VALUE_STRING;
+
+const ISE_TYPE_VALUE_STRING ISE_RETURN_KEY_TYPES[] = {
+    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT, "default"},
+    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DONE, "done"},
+    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_GO, "go"},
+    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_JOIN, "join"},
+    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_LOGIN, "login"},
+    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_NEXT, "next"},
+    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEARCH, "search"},
+    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEND, "send"},
+    {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SIGNIN, "signin"},
+};
+
+const ISE_TYPE_VALUE_STRING ISE_LAYOUT_TYPES[] = {
+    {ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL, "normal"},
+    {ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBER, "number"},
+    {ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL, "email"},
+    {ECORE_IMF_INPUT_PANEL_LAYOUT_URL, "url"},
+    {ECORE_IMF_INPUT_PANEL_LAYOUT_PHONENUMBER, "phonenumber"},
+    {ECORE_IMF_INPUT_PANEL_LAYOUT_IP, "ip"},
+    {ECORE_IMF_INPUT_PANEL_LAYOUT_MONTH, "month"},
+    {ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY, "numberonly"},
+    {ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD, "password"},
+    {ECORE_IMF_INPUT_PANEL_LAYOUT_DATETIME, "datetime"},
+};
+
+const ISE_TYPE_VALUE_STRING ISE_LANGUAGE_TYPES[] = {
+    {ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC, "automatic"},
+    {ECORE_IMF_INPUT_PANEL_LANG_ALPHABET, "alphabet"},
+};
+
+/* FIXME : Should consider the case if the boolean value does not match with EINA_TRUE or EINA_FALSE */
+const ISE_TYPE_VALUE_STRING ISE_TRUEFALSE_TYPES[] = {
+    {EINA_FALSE, "false"},
+    {EINA_TRUE, "true"},
+};
+
+class CISEMessageSerializer
+{
+protected:
+    /* FIXME : Temporary solution for distinguish commands and values */
+    static const char MESSAGE_DELIMETER = ' ';
+
+public:
+    static std::string serialize(ISE_MESSAGE message) {
+        std::string ret;
+        ret += message.type;
+        ret += MESSAGE_DELIMETER;
+        ret += message.command;
+        for (unsigned int loop = 0;loop < message.values.size();loop++) {
+            ret += MESSAGE_DELIMETER;
+            ret += message.values.at(loop);
+        }
+        return ret;
+    }
+
+    static ISE_MESSAGE deserialize(std::string message) {
+        ISE_MESSAGE ret;
+        std::vector<std::string> vec = CStringTokenizer::split(message, MESSAGE_DELIMETER);
+        if (vec.size() > 1) {
+            ret.type = vec.at(0);
+            vec.erase(vec.begin());
+            ret.command = vec.at(0);
+            vec.erase(vec.begin());
+            ret.values = vec;
+        }
+        return ret;
+    }
+
+    static bool valid(std::string str)
+    {
+        int loop;
+
+        bool valid_type = false;
+        bool valid_command = false;
+
+        ISE_MESSAGE message;
+        message = deserialize(str);
+
+        for (loop = 0;!valid_type && loop < ISE_MESSAGE_TYPES_NUM;loop++) {
+            if (message.type.compare(ISE_MESSAGE_TYPE_STRINGS[loop]) == 0) {
+                valid_type = true;
+            }
+        }
+        for (loop = 0;!valid_command && loop < ISE_MESSAGE_COMMANDS_NUM;loop++) {
+            if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[loop]) == 0) {
+                valid_command = true;
+            }
+        }
+
+        return (valid_type && valid_command);
+    }
+};
+
+class CWebHelperAgentWebSocket : public CWebHelperAgent {
+public:
+    CWebHelperAgentWebSocket();
+    virtual ~CWebHelperAgentWebSocket();
+
+    bool init();
+    bool exit();
+
+    bool run();
+
+    bool initialized() { return m_initialized; }
+
+    void signal(int sig);
+
+    void on_init();
+    void on_exit();
+
+    void on_focus_in(int ic);
+    void on_focus_out(int ic);
+
+    void on_show(int ic);
+    void on_hide(int ic);
+
+    void on_set_rotation(int degree);
+
+    void on_update_cursor_position(int ic, int cursor_pos);
+    void on_update_surrounding_text(int ic, const char *text, int cursor);
+    void on_update_selection(int ic, const char *text);
+
+    void on_set_language(unsigned int language);
+
+    void on_set_imdata(char *buf, unsigned int len);
+    void on_get_imdata(char **buf, unsigned int *len);
+
+    void on_set_return_key_type(unsigned int type);
+    void on_get_return_key_type(unsigned int *type);
+
+    void on_set_return_key_disable(unsigned int disabled);
+    void on_get_return_key_disable(unsigned int *disabled);
+
+    void on_set_layout(unsigned int layout);
+    void on_get_layout(unsigned int *layout);
+
+    void on_reset_input_context(int ic);
+
+    void on_process_key_event(unsigned int code, unsigned int mask, unsigned int layout, unsigned int *ret);
+
+    std::queue<ISE_MESSAGE>& get_send_message_queue();
+    std::queue<ISE_MESSAGE>& get_recv_message_queue();
+    Ecore_Pipe* get_message_pipe();
+
+    void wait_for_reply_message();
+
+    void process_recved_messages();
+    bool process_recved_messages_until_reply_found(std::string command, std::vector<std::string> &values);
+    void handle_recved_message(ISE_MESSAGE &message);
+
+    static CWebHelperAgentWebSocket* get_current_instance();
+protected:
+    static CWebHelperAgentWebSocket *m_current_instance;
+
+    std::queue<ISE_MESSAGE> m_send_message_queue;
+    std::queue<ISE_MESSAGE> m_recv_message_queue;
+
+    Ecore_Pipe *m_message_pipe;
+
+    bool m_initialized;
+};
+
+#endif // _WEB_HELPER_AGENT_WEBSOCKET_H_