Merge branch 'tizen_6.0' into tizen
[platform/core/uifw/libscl-core.git] / src / websocket.h
1 /*
2  * Copyright (c) 2012 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #ifndef _WEB_HELPER_AGENT_WEBSOCKET_H_
19 #define _WEB_HELPER_AGENT_WEBSOCKET_H_
20
21 #include "web_helper_agent.h"
22
23 #include <queue>
24
25 #include <Ecore.h>
26 #include <Eina.h>
27 #include <Ecore_IMF.h>
28
29 /* Wait for at most 1 second */
30 const struct timeval REPLY_TIMEOUT = {1, 0};
31
32 typedef enum {
33     ISE_MESSAGE_TYPE_PLAIN,
34     ISE_MESSAGE_TYPE_QUERY,
35     ISE_MESSAGE_TYPE_REPLY,
36
37     ISE_MESSAGE_TYPES_NUM,
38 } ISE_MESSAGE_TYPES;
39
40 const std::string ISE_MESSAGE_TYPE_STRINGS[] = {
41     "plain", // ISE_MESSAGE_TYPE_PLAIN,
42     "query", // ISE_MESSAGE_TYPE_QUERY
43     "reply", // ISE_MESSAGE_TYPE_REPLY
44 };
45
46 typedef enum {
47     ISE_MESSAGE_COMMAND_INIT,
48     ISE_MESSAGE_COMMAND_EXIT,
49
50     ISE_MESSAGE_COMMAND_FOCUS_IN,
51     ISE_MESSAGE_COMMAND_FOCUS_OUT,
52     ISE_MESSAGE_COMMAND_SHOW,
53     ISE_MESSAGE_COMMAND_HIDE,
54     ISE_MESSAGE_COMMAND_SET_ROTATION,
55     ISE_MESSAGE_COMMAND_UPDATE_CURSOR_POSITION,
56     ISE_MESSAGE_COMMAND_UPDATE_SURROUNDING_TEXT,
57     ISE_MESSAGE_COMMAND_UPDATE_SELECTION,
58     ISE_MESSAGE_COMMAND_SET_LANGUAGE,
59     ISE_MESSAGE_COMMAND_SET_IMDATA,
60     ISE_MESSAGE_COMMAND_GET_IMDATA,
61     ISE_MESSAGE_COMMAND_SET_RETURN_KEY_TYPE,
62     ISE_MESSAGE_COMMAND_GET_RETURN_KEY_TYPE,
63     ISE_MESSAGE_COMMAND_SET_RETURN_KEY_DISABLE,
64     ISE_MESSAGE_COMMAND_GET_RETURN_KEY_DISABLE,
65     ISE_MESSAGE_COMMAND_SET_LAYOUT,
66     ISE_MESSAGE_COMMAND_GET_LAYOUT,
67     ISE_MESSAGE_COMMAND_RESET_INPUT_CONTEXT,
68     ISE_MESSAGE_COMMAND_PROCESS_KEY_EVENT,
69
70     ISE_MESSAGE_COMMAND_LOG,
71     ISE_MESSAGE_COMMAND_COMMIT_STRING,
72     ISE_MESSAGE_COMMAND_UPDATE_PREEDIT_STRING,
73     ISE_MESSAGE_COMMAND_SEND_KEY_EVENT,
74     ISE_MESSAGE_COMMAND_FORWARD_KEY_EVENT,
75     ISE_MESSAGE_COMMAND_SET_KEYBOARD_SIZES,
76     ISE_MESSAGE_COMMAND_SET_SELECTION,
77     ISE_MESSAGE_COMMAND_GET_SELECTION,
78     ISE_MESSAGE_COMMAND_GET_SURROUNDING_TEXT,
79     ISE_MESSAGE_COMMAND_DELETE_SURROUNDING_TEXT,
80     ISE_MESSAGE_COMMAND_LOGIN,
81
82     ISE_MESSAGE_COMMANDS_NUM,
83 } ISE_MESSAGE_COMMANDS;
84
85 const std::string ISE_MESSAGE_COMMAND_STRINGS[] = {
86     "init", // ISE_MESSAGE_COMMAND_INIT,
87     "exit", // ISE_MESSAGE_COMMAND_EXIT,
88
89     "focus_in", // ISE_MESSAGE_COMMAND_FOCUS_IN,
90     "focus_out", // ISE_MESSAGE_COMMAND_FOCUS_OUT,
91     "show", // ISE_MESSAGE_COMMAND_SHOW,
92     "hide", // ISE_MESSAGE_COMMAND_HIDE,
93     "set_rotation", // ISE_MESSAGE_COMMAND_SET_ROTATION,
94     "update_cursor_position", // ISE_MESSAGE_COMMAND_UPDATE_CURSOR_POSITION,
95     "update_surrounding_text", // ISE_MESSAGE_COMMAND_UPDATE_SURROUNDING_TEXT,
96     "update_selection", // ISE_MESSAGE_COMMAND_UPDATE_SELECTION
97     "set_language", // ISE_MESSAGE_COMMAND_SET_LANGUAGE,
98     "set_imdata", // ISE_MESSAGE_COMMAND_SET_IMDATA,
99     "get_imdata", // ISE_MESSAGE_COMMAND_GET_IMDATA,
100     "set_return_key_type", // ISE_MESSAGE_COMMAND_SET_RETURN_KEY_TYPE,
101     "get_return_key_type", // ISE_MESSAGE_COMMAND_GET_RETURN_KEY_TYPE,
102     "set_return_key_disable", // ISE_MESSAGE_COMMAND_SET_RETURN_KEY_DISABLE,
103     "get_return_key_disable", // ISE_MESSAGE_COMMAND_GET_RETURN_KEY_DISABLE,
104     "set_layout", // ISE_MESSAGE_COMMAND_SET_LAYOUT,
105     "get_layout", // ISE_MESSAGE_COMMAND_GET_LAYOUT,
106     "reset_input_context", // ISE_MESSAGE_COMMAND_RESET_INPUT_CONTEXT,
107     "process_key_event", // ISE_MESSAGE_COMMAND_PROCESS_KEY_EVENT,
108
109     "log", // ISE_MESSAGE_COMMAND_LOG,
110     "commit_string", // ISE_MESSAGE_COMMAND_COMMIT_STRING,
111     "update_preedit_string", // ISE_MESSAGE_COMMAND_UPDATE_PREEDIT_STRING,
112     "send_key_event", // ISE_MESSAGE_COMMAND_SEND_KEY_EVENT,
113     "forward_key_event", // ISE_MESSAGE_COMMAND_FORWARD_KEY_EVENT,
114     "set_keyboard_sizes", // ISE_MESSAGE_COMMAND_SET_KEYBOARD_SIZES,
115     "set_selection", // ISE_MESSAGE_COMMAND_SET_SELECTION,
116     "get_selection", // ISE_MESSAGE_COMMAND_GET_SELECTION,
117     "get_surrounding_text", // ISE_MESSAGE_COMMAND_GET_SURROUNDING_TEXT,
118     "delete_surrounding_text", // ISE_MESSAGE_COMMAND_DELETE_SURROUNDING_TEXT,
119     "login", // ISE_MESSAGE_COMMAND_LOGIN,
120 };
121
122 typedef struct {
123     std::string type;
124     std::string command;
125     std::vector<std::string> values;
126 } ISE_MESSAGE;
127
128 typedef struct {
129     int type_value;
130     std::string type_string;
131 } ISE_TYPE_VALUE_STRING;
132
133 const ISE_TYPE_VALUE_STRING ISE_RETURN_KEY_TYPES[] = {
134     {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT, "default"},
135     {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DONE, "done"},
136     {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_GO, "go"},
137     {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_JOIN, "join"},
138     {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_LOGIN, "login"},
139     {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_NEXT, "next"},
140     {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEARCH, "search"},
141     {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEND, "send"},
142     {ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SIGNIN, "signin"},
143 };
144
145 const ISE_TYPE_VALUE_STRING ISE_LAYOUT_TYPES[] = {
146     {ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL, "normal"},
147     {ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBER, "number"},
148     {ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL, "email"},
149     {ECORE_IMF_INPUT_PANEL_LAYOUT_URL, "url"},
150     {ECORE_IMF_INPUT_PANEL_LAYOUT_PHONENUMBER, "phonenumber"},
151     {ECORE_IMF_INPUT_PANEL_LAYOUT_IP, "ip"},
152     {ECORE_IMF_INPUT_PANEL_LAYOUT_MONTH, "month"},
153     {ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY, "numberonly"},
154     {ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD, "password"},
155     {ECORE_IMF_INPUT_PANEL_LAYOUT_DATETIME, "datetime"},
156 };
157
158 const ISE_TYPE_VALUE_STRING ISE_LANGUAGE_TYPES[] = {
159     {ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC, "automatic"},
160     {ECORE_IMF_INPUT_PANEL_LANG_ALPHABET, "alphabet"},
161 };
162
163 /* FIXME : Should consider the case if the boolean value does not match with EINA_TRUE or EINA_FALSE */
164 const ISE_TYPE_VALUE_STRING ISE_TRUEFALSE_TYPES[] = {
165     {EINA_FALSE, "false"},
166     {EINA_TRUE, "true"},
167 };
168
169 class CISEMessageSerializer
170 {
171 protected:
172     /* FIXME : Temporary solution for distinguish commands and values */
173     static const char MESSAGE_DELIMETER = ' ';
174
175 public:
176     static std::string serialize(ISE_MESSAGE message) {
177         std::string ret;
178         ret += message.type;
179         ret += MESSAGE_DELIMETER;
180         ret += message.command;
181         for (unsigned int loop = 0;loop < message.values.size();loop++) {
182             ret += MESSAGE_DELIMETER;
183             ret += message.values.at(loop);
184         }
185         return ret;
186     }
187
188     static ISE_MESSAGE deserialize(std::string message) {
189         ISE_MESSAGE ret;
190         std::vector<std::string> vec = CStringTokenizer::split(message, MESSAGE_DELIMETER);
191         if (vec.size() > 1) {
192             ret.type = vec.at(0);
193             vec.erase(vec.begin());
194             ret.command = vec.at(0);
195             vec.erase(vec.begin());
196             ret.values = vec;
197         }
198         return ret;
199     }
200
201     static bool valid(std::string str)
202     {
203         int loop;
204
205         bool valid_type = false;
206         bool valid_command = false;
207
208         ISE_MESSAGE message;
209         message = deserialize(str);
210
211         for (loop = 0;!valid_type && loop < ISE_MESSAGE_TYPES_NUM;loop++) {
212             if (message.type.compare(ISE_MESSAGE_TYPE_STRINGS[loop]) == 0) {
213                 valid_type = true;
214             }
215         }
216         for (loop = 0;!valid_command && loop < ISE_MESSAGE_COMMANDS_NUM;loop++) {
217             if (message.command.compare(ISE_MESSAGE_COMMAND_STRINGS[loop]) == 0) {
218                 valid_command = true;
219             }
220         }
221
222         return (valid_type && valid_command);
223     }
224 };
225
226 class CWebHelperAgentWebSocket : public CWebHelperAgent {
227 public:
228     CWebHelperAgentWebSocket();
229     virtual ~CWebHelperAgentWebSocket();
230
231     bool init();
232     bool exit();
233
234     bool run();
235
236     bool initialized() { return m_initialized; }
237
238     void signal(int sig);
239
240     void on_init();
241     void on_exit();
242
243     void on_focus_in(int ic);
244     void on_focus_out(int ic);
245
246     void on_show(int ic);
247     void on_hide(int ic);
248
249     void on_set_rotation(int degree);
250
251     void on_update_cursor_position(int ic, int cursor_pos);
252     void on_update_surrounding_text(int ic, const char *text, int cursor);
253     void on_update_selection(int ic, const char *text);
254
255     void on_set_language(unsigned int language);
256
257     void on_set_imdata(char *buf, unsigned int len);
258     void on_get_imdata(char **buf, unsigned int *len);
259
260     void on_set_return_key_type(unsigned int type);
261     void on_get_return_key_type(unsigned int *type);
262
263     void on_set_return_key_disable(unsigned int disabled);
264     void on_get_return_key_disable(unsigned int *disabled);
265
266     void on_set_layout(unsigned int layout);
267     void on_get_layout(unsigned int *layout);
268
269     void on_reset_input_context(int ic);
270
271     void on_process_key_event(unsigned int code, unsigned int mask, unsigned int layout, unsigned int *ret);
272
273     std::queue<ISE_MESSAGE>& get_send_message_queue();
274     std::queue<ISE_MESSAGE>& get_recv_message_queue();
275     Ecore_Pipe* get_message_pipe();
276
277     void wait_for_reply_message();
278
279     void process_recved_messages();
280     bool process_recved_messages_until_reply_found(std::string command, std::vector<std::string> &values);
281     void handle_recved_message(ISE_MESSAGE &message);
282
283     static CWebHelperAgentWebSocket* get_current_instance();
284 protected:
285     static CWebHelperAgentWebSocket *m_current_instance;
286
287     std::queue<ISE_MESSAGE> m_send_message_queue;
288     std::queue<ISE_MESSAGE> m_recv_message_queue;
289
290     Ecore_Pipe *m_message_pipe;
291
292     bool m_initialized;
293 };
294
295 #endif // _WEB_HELPER_AGENT_WEBSOCKET_H_