Revert "Add SocketConfigServer PanelAgent module"
[platform/core/uifw/isf.git] / ism / modules / config / scim_socket_config.cpp
1 /** @file scim_socket_config.cpp
2  * implementation of SocketConfig class.
3  */
4 /* ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable. */
5
6 /*
7  * Smart Common Input Method
8  *
9  * Copyright (c) 2002-2005 James Su <suzhe@tsinghua.org.cn>
10  *
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with this program; if not, write to the
24  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
25  * Boston, MA  02111-1307  USA
26  *
27  * $Id: scim_socket_config.cpp,v 1.23 2005/12/16 11:12:26 suzhe Exp $
28  */
29
30 #define Uses_SCIM_CONFIG_BASE
31 #define Uses_SCIM_CONFIG_PATH
32 #define Uses_SCIM_SOCKET
33 #define Uses_SCIM_TRANSACTION
34 #define Uses_C_STDIO
35 #define Uses_C_STDLIB
36
37 #include "scim_private.h"
38 #include "scim.h"
39 #include "scim_socket_config.h"
40
41 #include <dlog.h>
42 #include "isf_debug.h"
43
44 #ifdef LOG_TAG
45 # undef LOG_TAG
46 #endif
47 #define LOG_TAG "ISF_SOCKET_CONFIG"
48
49
50 #define scim_module_init socket_LTX_scim_module_init
51 #define scim_module_exit socket_LTX_scim_module_exit
52 #define scim_config_module_init socket_LTX_scim_config_module_init
53 #define scim_config_module_create_config socket_LTX_scim_config_module_create_config
54
55 using namespace scim;
56
57 extern "C" {
58     EXAPI void scim_module_init (void)
59     {
60         SCIM_DEBUG_CONFIG(1) << "Initializing Socket Config module...\n";
61     }
62
63     EXAPI void scim_module_exit (void)
64     {
65         SCIM_DEBUG_CONFIG(1) << "Exiting Socket Config module...\n";
66     }
67
68     EXAPI void scim_config_module_init ()
69     {
70         SCIM_DEBUG_CONFIG(1) << "Initializing Socket Config module (more)...\n";
71     }
72
73     EXAPI ConfigPointer scim_config_module_create_config ()
74     {
75         SCIM_DEBUG_CONFIG(1) << "Creating a Socket Config instance...\n";
76         return new SocketConfig ();
77     }
78 }
79
80 namespace scim {
81
82 SocketConfig::SocketConfig ()
83     : m_socket_address (scim_get_default_socket_config_address ()),
84       m_socket_timeout (scim_get_default_socket_timeout ()),
85       m_valid (false),
86       m_connected (false)
87 {
88     SCIM_DEBUG_CONFIG (2) << " Construct SocketConfig object.\n";
89
90     String display_name;
91     {
92         const char *p = getenv ("DISPLAY");
93         if (p) display_name = String (p);
94     }
95     m_socket_address = scim_get_default_panel_socket_address (display_name);
96
97     m_valid = open_connection ();
98 }
99
100 SocketConfig::~SocketConfig ()
101 {
102     m_socket_client.close ();
103 }
104
105 bool
106 SocketConfig::valid () const
107 {
108     return ConfigBase::valid() && m_valid;
109 }
110
111 String
112 SocketConfig::get_name () const
113 {
114     return "socket";
115 }
116
117 // String
118 bool
119 SocketConfig::read (const String& key, String *pStr) const
120 {
121     LOGV ("");
122     if (!valid () || !pStr || key.empty()) return false;
123     if (!m_connected && !open_connection ()) return false;
124
125     Transaction trans;
126
127     int cmd;
128
129     for (int retry = 0; retry < 3; ++retry) {
130         init_transaction (trans);
131         trans.put_command (SCIM_TRANS_CMD_GET_CONFIG_STRING);
132         trans.put_data (key);
133
134         if (trans.write_to_socket (m_socket_client) &&
135             trans.read_from_socket (m_socket_client, m_socket_timeout)) {
136             if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
137                 trans.get_data (*pStr) &&
138                 trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK)
139                 return true;
140
141             break;
142         }
143         LOGW ("Failed, reconnect again");
144         if (!open_connection ())
145             break;
146     }
147
148     *pStr = String ("");
149     return false;
150 }
151
152 // int
153 bool
154 SocketConfig::read (const String& key, int *pl) const
155 {
156     LOGV ("");
157     if (!valid () || !pl || key.empty()) return false;
158     if (!m_connected && !open_connection ()) return false;
159
160     Transaction trans;
161     int cmd;
162
163     for (int retry = 0; retry < 3; ++retry) {
164         init_transaction (trans);
165         trans.put_command (SCIM_TRANS_CMD_GET_CONFIG_INT);
166         trans.put_data (key);
167
168         if (trans.write_to_socket (m_socket_client) &&
169             trans.read_from_socket (m_socket_client, m_socket_timeout)) {
170             uint32 val;
171             if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
172                 trans.get_data (val) &&
173                 trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
174                 *pl = val;
175                 return true;
176             }
177
178             break;
179         }
180         LOGW ("Failed, reconnect again");
181         if (!open_connection ())
182             break;
183     }
184
185     *pl = 0;
186     return false;
187 }
188
189 // double
190 bool
191 SocketConfig::read (const String& key, double* val) const
192 {
193     LOGV ("");
194     if (!valid () || !val || key.empty()) return false;
195     if (!m_connected && !open_connection ()) return false;
196
197     Transaction trans;
198     int cmd;
199
200     for (int retry = 0; retry < 3; ++retry) {
201         init_transaction (trans);
202         trans.put_command (SCIM_TRANS_CMD_GET_CONFIG_DOUBLE);
203         trans.put_data (key);
204
205         if (trans.write_to_socket (m_socket_client) &&
206             trans.read_from_socket (m_socket_client, m_socket_timeout)) {
207             String str;
208             if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
209                 trans.get_data (str) &&
210                 trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
211                 sscanf (str.c_str (), "%lE", val);
212                 return true;
213             }
214
215             break;
216         }
217         LOGW ("Failed, reconnect again");
218         if (!open_connection ())
219             break;
220     }
221
222     *val = 0;
223     return false;
224 }
225
226 // bool
227 bool
228 SocketConfig::read (const String& key, bool* val) const
229 {
230     LOGV ("");
231     if (!valid () || !val || key.empty()) return false;
232     if (!m_connected && !open_connection ()) return false;
233
234     Transaction trans;
235     int cmd;
236
237     for (int retry = 0; retry < 3; ++retry) {
238         init_transaction (trans);
239         trans.put_command (SCIM_TRANS_CMD_GET_CONFIG_BOOL);
240         trans.put_data (key);
241
242         if (trans.write_to_socket (m_socket_client) &&
243             trans.read_from_socket (m_socket_client, m_socket_timeout)) {
244             uint32 tmp;
245             if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
246                 trans.get_data (tmp) &&
247                 trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
248                 *val = (bool)tmp;
249                 return true;
250             }
251
252             break;
253         }
254         LOGW ("Failed, reconnect again");
255         if (!open_connection ())
256             break;
257     }
258
259     *val = false;
260     return false;
261 }
262
263 //String list
264 bool
265 SocketConfig::read (const String& key, std::vector <String>* val) const
266 {
267     LOGV ("");
268     if (!valid () || !val || key.empty()) return false;
269     if (!m_connected && !open_connection ()) return false;
270
271     val->clear ();
272
273     Transaction trans;
274     int cmd;
275
276     for (int retry = 0; retry < 3; ++retry) {
277         init_transaction (trans);
278         trans.put_command (SCIM_TRANS_CMD_GET_CONFIG_VECTOR_STRING);
279         trans.put_data (key);
280
281         if (trans.write_to_socket (m_socket_client) &&
282             trans.read_from_socket (m_socket_client, m_socket_timeout)) {
283             if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
284                 trans.get_data (*val) &&
285                 trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
286                 return true;
287             }
288
289             break;
290         }
291         LOGW ("Failed, reconnect again");
292         if (!open_connection ())
293             break;
294     }
295
296     return false;
297 }
298
299 //int list
300 bool
301 SocketConfig::read (const String& key, std::vector <int>* val) const
302 {
303     LOGV ("");
304     if (!valid () || !val || key.empty()) return false;
305     if (!m_connected && !open_connection ()) return false;
306
307     val->clear();
308
309     Transaction trans;
310     int cmd;
311
312     for (int retry = 0; retry < 3; ++retry) {
313         init_transaction (trans);
314         trans.put_command (SCIM_TRANS_CMD_GET_CONFIG_VECTOR_INT);
315         trans.put_data (key);
316
317         if (trans.write_to_socket (m_socket_client) &&
318             trans.read_from_socket (m_socket_client, m_socket_timeout)) {
319             std::vector<uint32> vec;
320             if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
321                 trans.get_data (vec) &&
322                 trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
323                 for (uint32 i=0; i<vec.size (); ++i)
324                     val->push_back ((int) vec[i]);
325                 return true;
326             }
327
328             break;
329         }
330         LOGW ("Failed, reconnect again");
331         if (!open_connection ())
332             break;
333     }
334
335     return false;
336 }
337
338 // write the value (return true on success)
339 bool
340 SocketConfig::write (const String& key, const String& value)
341 {
342     LOGV ("");
343     if (!valid () || key.empty()) return false;
344     if (!m_connected && !open_connection ()) return false;
345
346     Transaction trans;
347
348     for (int retry = 0; retry < 3; ++retry) {
349         init_transaction (trans);
350         trans.put_command (SCIM_TRANS_CMD_SET_CONFIG_STRING);
351         trans.put_data (key);
352         trans.put_data (value);
353
354         if (trans.write_to_socket (m_socket_client)) {
355             return true;
356         }
357         LOGW ("Failed, reconnect again");
358         if (!open_connection ())
359             break;
360     }
361
362     return false;
363 }
364
365 bool
366 SocketConfig::write (const String& key, int value)
367 {
368     LOGV ("");
369     if (!valid () || key.empty()) return false;
370     if (!m_connected && !open_connection ()) return false;
371
372     Transaction trans;
373
374     for (int retry = 0; retry < 3; ++retry) {
375         init_transaction (trans);
376         trans.put_command (SCIM_TRANS_CMD_SET_CONFIG_INT);
377         trans.put_data (key);
378         trans.put_data ((uint32)value);
379
380         if (trans.write_to_socket (m_socket_client)) {
381             return true;
382         }
383         LOGW ("Failed, reconnect again");
384         if (!open_connection ())
385             break;
386     }
387
388     return false;
389 }
390
391 bool
392 SocketConfig::write (const String& key, double value)
393 {
394     LOGV ("");
395     if (!valid () || key.empty()) return false;
396     if (!m_connected && !open_connection ()) return false;
397
398     char buf [256];
399     snprintf (buf, 255, "%lE", value);
400
401     Transaction trans;
402
403     for (int retry = 0; retry < 3; ++retry) {
404         init_transaction (trans);
405         trans.put_command (SCIM_TRANS_CMD_SET_CONFIG_DOUBLE);
406         trans.put_data (key);
407         trans.put_data (String (buf));
408
409         if (trans.write_to_socket (m_socket_client)) {
410             return true;
411         }
412         LOGW ("Failed, reconnect again");
413         if (!open_connection ())
414             break;
415     }
416
417     return false;
418 }
419
420 bool
421 SocketConfig::write (const String& key, bool value)
422 {
423     LOGV ("");
424     if (!valid () || key.empty()) return false;
425     if (!m_connected && !open_connection ()) return false;
426
427     Transaction trans;
428
429     for (int retry = 0; retry < 3; ++retry) {
430         init_transaction (trans);
431         trans.put_command (SCIM_TRANS_CMD_SET_CONFIG_BOOL);
432         trans.put_data (key);
433         trans.put_data ((uint32)value);
434
435         if (trans.write_to_socket (m_socket_client)) {
436             return true;
437         }
438         LOGW ("Failed, reconnect again");
439         if (!open_connection ())
440             break;
441     }
442
443     return false;
444 }
445
446 bool
447 SocketConfig::write (const String& key, const std::vector <String>& value)
448 {
449     LOGV ("");
450     if (!valid () || key.empty()) return false;
451     if (!m_connected && !open_connection ()) return false;
452
453     Transaction trans;
454
455     for (int retry = 0; retry < 3; ++retry) {
456         init_transaction (trans);
457         trans.put_command (SCIM_TRANS_CMD_SET_CONFIG_VECTOR_STRING);
458         trans.put_data (key);
459         trans.put_data (value);
460
461         if (trans.write_to_socket (m_socket_client)) {
462             return true;
463         }
464         LOGW ("Failed, reconnect again");
465         if (!open_connection ())
466             break;
467     }
468
469     return false;
470 }
471
472 bool
473 SocketConfig::write (const String& key, const std::vector <int>& value)
474 {
475     LOGV ("");
476     if (!valid () || key.empty()) return false;
477     if (!m_connected && !open_connection ()) return false;
478
479     std::vector <uint32> vec;
480
481     for (uint32 i=0; i<value.size (); ++i)
482         vec.push_back ((uint32) value [i]);
483
484     Transaction trans;
485
486     for (int retry = 0; retry < 3; ++retry) {
487         init_transaction (trans);
488         trans.put_command (SCIM_TRANS_CMD_SET_CONFIG_VECTOR_INT);
489         trans.put_data (key);
490         trans.put_data (vec);
491
492         if (trans.write_to_socket (m_socket_client)) {
493             return true;
494         }
495         LOGW ("Failed, reconnect again");
496         if (!open_connection ())
497             break;
498     }
499
500     return false;
501 }
502
503 // permanently writes all changes
504 bool
505 SocketConfig::flush ()
506 {
507     LOGD ("");
508     if (!valid ()) return false;
509     if (!m_connected && !open_connection ()) return false;
510
511     Transaction trans;
512
513     for (int retry = 0; retry < 3; ++retry) {
514         init_transaction (trans);
515         trans.put_command (SCIM_TRANS_CMD_FLUSH_CONFIG);
516
517         if (trans.write_to_socket (m_socket_client)) {
518             gettimeofday (&m_update_timestamp, 0);
519             return true;
520         }
521         LOGW ("Failed, reconnect again");
522         if (!open_connection ())
523             break;
524     }
525
526     return false;
527 }
528
529 // delete entries
530 bool
531 SocketConfig::erase (const String& key)
532 {
533     LOGD ("");
534     if (!valid ()) return false;
535     if (!m_connected && !open_connection ()) return false;
536
537     Transaction trans;
538
539     for (int retry = 0; retry < 3; ++retry) {
540         init_transaction (trans);
541         trans.put_command (SCIM_TRANS_CMD_ERASE_CONFIG);
542         trans.put_data (key);
543
544         if (trans.write_to_socket (m_socket_client)) {
545             return true;
546         }
547         LOGW ("Failed, reconnect again");
548         if (!open_connection ())
549             break;
550     }
551
552     return false;
553 }
554
555 bool
556 SocketConfig::reload ()
557 {
558     LOGD ("");
559     if (!valid ()) return false;
560     if (!m_connected && !open_connection ()) return false;
561
562     Transaction trans;
563     int cmd;
564
565     for (int retry = 0; retry < 3; ++retry) {
566         init_transaction (trans);
567         trans.put_command (SCIM_TRANS_CMD_RELOAD_CONFIG);
568
569         // The reload process may take very long time, so wait a little longer time.
570         if (trans.write_to_socket (m_socket_client) &&
571             trans.read_from_socket (m_socket_client, m_socket_timeout * 10)) {
572             if (trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
573                 trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
574                 String str;
575                 if (read (String (SCIM_CONFIG_UPDATE_TIMESTAMP), &str)) {
576                     std::vector <String> strs;
577                     if (scim_split_string_list (strs, str, ':') == 2) {
578                         time_t sec = (time_t) strtol (strs [0].c_str (), 0, 10);
579                         suseconds_t usec = (suseconds_t) strtol (strs [1].c_str (), 0, 10);
580
581                         // The config file is newer, so load it.
582                         if (m_update_timestamp.tv_sec < sec ||
583                             (m_update_timestamp.tv_sec == sec && m_update_timestamp.tv_usec < usec)) {
584                             m_update_timestamp.tv_sec = sec;
585                             m_update_timestamp.tv_usec = usec;
586                             return ConfigBase::reload ();
587                         }
588                     }
589                 }
590             }
591             break;
592         }
593         LOGW ("Failed reconnect again");
594         if (!open_connection ())
595             break;
596     }
597
598     return false;
599 }
600
601 void
602 SocketConfig::init_transaction (Transaction &trans) const
603 {
604     trans.clear ();
605     trans.put_command (SCIM_TRANS_CMD_REQUEST);
606     trans.put_data (m_socket_magic_key);
607 }
608
609 bool
610 SocketConfig::open_connection () const
611 {
612     SocketAddress socket_address (m_socket_address);
613
614     m_connected = false;
615
616     // Connect to SocketServer.
617     if (!m_socket_client.connect (socket_address)) {
618         /* Retry connecting considering the ANR timeout */
619         for (int i = 0; i < 3; ++i) {
620             if (m_socket_client.connect (socket_address))
621                 break;
622             scim_usleep (100000);
623             LOGW (" Re-connecting to ISF(scim) server. SocketConfig connect count : %d\n", i+1);
624         }
625     }
626
627     if (!m_socket_client.is_connected ()) {
628         LOGW (" Cannot connect to SocketServer (%s).\n", m_socket_address.c_str ());
629         return false;
630     }
631
632     // Init the connection,
633     if (!scim_socket_open_connection (m_socket_magic_key,
634                                       String ("SocketConfig"),
635                                       String ("Panel"),
636                                       m_socket_client,
637                                       m_socket_timeout)) {
638         m_socket_client.close ();
639         LOGE (" Connect to SocketServer (%s) failed.\n", m_socket_address.c_str ());
640         return false;
641     }
642
643     LOGD (" Connect to SocketServer (%s).\n", m_socket_address.c_str ());
644     m_connected = true;
645     gettimeofday (&m_update_timestamp, 0);
646     return true;
647 }
648
649 } // namespace scim
650
651 /*
652 vi:ts=4:nowrap:ai:expandtab
653 */