Fix buxton key layer
[platform/core/uifw/stt.git] / client / stt.c
1 /*
2 *  Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14 #include <aul.h>
15 #include <cynara-client.h>
16 #include <cynara-error.h>
17 #include <cynara-session.h>
18 #include <dirent.h>
19 #include <Ecore.h>
20 #include <fcntl.h>
21 #include <pthread.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <sys/wait.h>
25 #include <system_info.h>
26 #include <unistd.h>
27 #include <buxton2.h>
28
29 #include "stt.h"
30 #include "stt_client.h"
31 #include "stt_dbus.h"
32 #include "stt_config_mgr.h"
33 #include "stt_main.h"
34
35
36 static void __stt_notify_state_changed(void *data);
37 static Eina_Bool __stt_notify_error(void *data);
38
39 static Ecore_Timer* g_connect_timer = NULL;
40 static float g_volume_db = 0;
41
42 static int g_feature_enabled = -1;
43
44 static int g_privilege_allowed = -1;
45 static cynara *p_cynara = NULL;
46
47 static bool g_err_callback_status = false;
48
49 const char* stt_tag()
50 {
51         return "sttc";
52 }
53
54 static int __stt_get_feature_enabled()
55 {
56         if (0 == g_feature_enabled) {
57                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] STT NOT supported");
58                 return STT_ERROR_NOT_SUPPORTED;
59         } else if (-1 == g_feature_enabled) {
60                 bool stt_supported = false;
61                 bool mic_supported = false;
62                 if (0 == system_info_get_platform_bool(STT_FEATURE_PATH, &stt_supported)) {
63                         if (0 == system_info_get_platform_bool(STT_MIC_FEATURE_PATH, &mic_supported)) {
64                                 if (false == stt_supported || false == mic_supported) {
65                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] STT NOT supported");
66                                         g_feature_enabled = 0;
67                                         return STT_ERROR_NOT_SUPPORTED;
68                                 }
69
70                                 g_feature_enabled = 1;
71                         } else {
72                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get feature value");
73                                 return STT_ERROR_NOT_SUPPORTED;
74                         }
75                 } else {
76                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get feature value");
77                         return STT_ERROR_NOT_SUPPORTED;
78                 }
79         }
80
81         return 0;
82 }
83
84 static int __check_privilege_initialize()
85 {
86         int ret = cynara_initialize(&p_cynara, NULL);
87         if (CYNARA_API_SUCCESS != ret)
88                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] fail to initialize");
89
90         return ret == CYNARA_API_SUCCESS;
91 }
92
93 static int __check_privilege(const char* uid, const char * privilege)
94 {
95         FILE *fp = NULL;
96         char label_path[1024] = "/proc/self/attr/current";
97         char smack_label[1024] = {'\0',};
98
99         if (!p_cynara) {
100             return false;
101         }
102
103         fp = fopen(label_path, "r");
104         if (fp != NULL) {
105             if (fread(smack_label, 1, sizeof(smack_label), fp) <= 0)
106                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] fail to fread");
107
108             fclose(fp);
109         }
110
111         pid_t pid = getpid();
112         char *session = cynara_session_from_pid(pid);
113         int ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
114         SLOG(LOG_DEBUG, TAG_STTC, "[Client]cynara_check returned %d(%s)", ret, (CYNARA_API_ACCESS_ALLOWED == ret) ? "Allowed" : "Denied");
115         if (session) {
116                 free(session);
117                 session = NULL;
118         }
119
120         if (ret != CYNARA_API_ACCESS_ALLOWED)
121             return false;
122         return true;
123 }
124
125 static void __check_privilege_deinitialize()
126 {
127         if (p_cynara)
128                 cynara_finish(p_cynara);
129         p_cynara = NULL;
130 }
131
132 static int __stt_check_privilege()
133 {
134         char uid[16];
135
136         if (0 == g_privilege_allowed) {
137                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Permission is denied");
138                 return STT_ERROR_PERMISSION_DENIED;
139         } else if (-1 == g_privilege_allowed) {
140                 if (false == __check_privilege_initialize()) {
141                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] privilege initialize is failed");
142                         return STT_ERROR_PERMISSION_DENIED;
143                 }
144                 snprintf(uid, 16, "%d", getuid());
145                 if (false == __check_privilege(uid, STT_PRIVILEGE)) {
146                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Permission is denied");
147                         g_privilege_allowed = 0;
148                         __check_privilege_deinitialize();
149                         return STT_ERROR_PERMISSION_DENIED;
150                 }
151                 __check_privilege_deinitialize();
152         }
153
154         g_privilege_allowed = 1;
155         return STT_ERROR_NONE;
156 }
157
158 static const char* __stt_get_error_code(stt_error_e err)
159 {
160         switch (err) {
161         case STT_ERROR_NONE:                    return "STT_ERROR_NONE";
162         case STT_ERROR_OUT_OF_MEMORY:           return "STT_ERROR_OUT_OF_MEMORY";
163         case STT_ERROR_IO_ERROR:                return "STT_ERROR_IO_ERROR";
164         case STT_ERROR_INVALID_PARAMETER:       return "STT_ERROR_INVALID_PARAMETER";
165         case STT_ERROR_TIMED_OUT:               return "STT_ERROR_TIMED_OUT";
166         case STT_ERROR_RECORDER_BUSY:           return "STT_ERROR_RECORDER_BUSY";
167         case STT_ERROR_OUT_OF_NETWORK:          return "STT_ERROR_OUT_OF_NETWORK";
168         case STT_ERROR_PERMISSION_DENIED:       return "STT_ERROR_PERMISSION_DENIED";
169         case STT_ERROR_NOT_SUPPORTED:           return "STT_ERROR_NOT_SUPPORTED";
170         case STT_ERROR_INVALID_STATE:           return "STT_ERROR_INVALID_STATE";
171         case STT_ERROR_INVALID_LANGUAGE:        return "STT_ERROR_INVALID_LANGUAGE";
172         case STT_ERROR_ENGINE_NOT_FOUND:        return "STT_ERROR_ENGINE_NOT_FOUND";
173         case STT_ERROR_OPERATION_FAILED:        return "STT_ERROR_OPERATION_FAILED";
174         case STT_ERROR_NOT_SUPPORTED_FEATURE:   return "STT_ERROR_NOT_SUPPORTED_FEATURE";
175         case STT_ERROR_SERVICE_RESET:           return "STT_ERROR_SERVICE_RESET";
176         default:
177                 return "Invalid error code";
178         }
179 }
180
181 static int __stt_convert_config_error_code(stt_config_error_e code)
182 {
183         if (code == STT_CONFIG_ERROR_NONE)                      return STT_ERROR_NONE;
184         if (code == STT_CONFIG_ERROR_OUT_OF_MEMORY)             return STT_ERROR_OUT_OF_MEMORY;
185         if (code == STT_CONFIG_ERROR_IO_ERROR)                  return STT_ERROR_IO_ERROR;
186         if (code == STT_CONFIG_ERROR_INVALID_PARAMETER)         return STT_ERROR_INVALID_PARAMETER;
187         if (code == STT_CONFIG_ERROR_PERMISSION_DENIED)         return STT_ERROR_PERMISSION_DENIED;
188         if (code == STT_CONFIG_ERROR_NOT_SUPPORTED)             return STT_ERROR_NOT_SUPPORTED;
189         if (code == STT_CONFIG_ERROR_INVALID_STATE)             return STT_ERROR_INVALID_STATE;
190         if (code == STT_CONFIG_ERROR_INVALID_LANGUAGE)          return STT_ERROR_INVALID_LANGUAGE;
191         if (code == STT_CONFIG_ERROR_ENGINE_NOT_FOUND)          return STT_ERROR_ENGINE_NOT_FOUND;
192         if (code == STT_CONFIG_ERROR_OPERATION_FAILED)          return STT_ERROR_OPERATION_FAILED;
193
194         return code;
195 }
196
197 void __stt_config_lang_changed_cb(const char* before_language, const char* current_language, void* user_data)
198 {
199         SLOG(LOG_DEBUG, TAG_STTC, "Language changed : Before lang(%s) Current lang(%s)",
200                 before_language, current_language);
201
202         if (0 == strcmp(before_language, current_language)) {
203                 return;
204         }
205
206         GList* client_list = NULL;
207         client_list = stt_client_get_client_list();
208
209         GList *iter = NULL;
210         stt_client_s *data = NULL;
211
212         if (g_list_length(client_list) > 0) {
213                 /* Get a first item */
214                 iter = g_list_first(client_list);
215
216                 while (NULL != iter) {
217                         data = iter->data;
218                         if (NULL != data->default_lang_changed_cb) {
219                                 SLOG(LOG_DEBUG, TAG_STTC, "Call default language changed callback : uid(%d)", data->uid);
220                                 data->default_lang_changed_cb(data->stt, before_language, current_language,
221                                         data->default_lang_changed_user_data);
222                         }
223
224                         /* Next item */
225                         iter = g_list_next(iter);
226                 }
227         }
228
229         return;
230 }
231
232 void __stt_config_engine_changed_cb(const char* engine_id, const char* setting, const char* language, bool support_silence, bool need_credential, void* user_data)
233 {
234         stt_h stt = (stt_h)user_data;
235
236         stt_client_s* client = stt_client_get(stt);
237         if (NULL == client) {
238                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] A handle is not valid");
239                 return;
240         }
241
242         if (NULL != engine_id)  SLOG(LOG_DEBUG, TAG_STTC, "Engine id(%s)", engine_id);
243         if (NULL != setting)    SLOG(LOG_DEBUG, TAG_STTC, "Engine setting(%s)", setting);
244         if (NULL != language)   SLOG(LOG_DEBUG, TAG_STTC, "Language(%s)", language);
245         SLOG(LOG_DEBUG, TAG_STTC, "Silence(%s), Credential(%s)", support_silence ? "on" : "off", need_credential ? "need" : "no need");
246
247         /* call callback function */
248         if (NULL != client->engine_changed_cb) {
249                 client->engine_changed_cb(stt, engine_id, language, support_silence, need_credential, client->engine_changed_user_data);
250         } else {
251                 SLOG(LOG_WARN, TAG_STTC, "No registered callback function for engine change");
252         }
253         return;
254 }
255
256 static int __stt_check_handle(stt_h stt, stt_client_s** client)
257 {
258         if (NULL == stt) {
259                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input handle is null");
260                 return STT_ERROR_INVALID_PARAMETER;
261         }
262
263         stt_client_s* temp = NULL;
264         temp = stt_client_get(stt);
265
266         /* check handle */
267         if (NULL == temp) {
268                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
269                 return STT_ERROR_INVALID_PARAMETER;
270         }
271         *client = temp;
272
273         return STT_ERROR_NONE;
274 }
275
276 int stt_create(stt_h* stt)
277 {
278         if (0 != __stt_get_feature_enabled()) {
279                 return STT_ERROR_NOT_SUPPORTED;
280         }
281         if (0 != __stt_check_privilege()) {
282                 return STT_ERROR_PERMISSION_DENIED;
283         }
284
285         SLOG(LOG_DEBUG, TAG_STTC, "===== Create STT");
286
287         if (NULL == stt) {
288                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is null");
289                 return STT_ERROR_INVALID_PARAMETER;
290         }
291
292         if (0 == stt_client_get_size()) {
293                 if (0 != stt_dbus_open_connection()) {
294                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to open connection");
295                         return STT_ERROR_OPERATION_FAILED;
296                 }
297         }
298
299         if (0 != stt_client_new(stt)) {
300                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to create client!");
301                 return STT_ERROR_OUT_OF_MEMORY;
302         }
303
304         stt_client_s* client = stt_client_get(*stt);
305         if (NULL == client) {
306                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to create client");
307                 stt_client_destroy(*stt);
308                 return STT_ERROR_OPERATION_FAILED;
309         }
310
311         int ret = stt_config_mgr_initialize(client->uid);
312         ret = __stt_convert_config_error_code(ret);
313         if (0 != ret) {
314                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to init config manager : %s", __stt_get_error_code(ret));
315                 stt_client_destroy(*stt);
316                 return ret;
317         }
318
319         ret = stt_config_mgr_set_callback(client->uid, __stt_config_engine_changed_cb, __stt_config_lang_changed_cb, NULL, client->stt);
320         ret = __stt_convert_config_error_code(ret);
321         if (0 != ret) {
322                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set config changed : %s", __stt_get_error_code(ret));
323                 stt_client_destroy(*stt);
324                 return ret;
325         }
326
327         SLOG(LOG_DEBUG, TAG_STTC, "[Success] uid(%d)", (*stt)->handle);
328
329         SLOG(LOG_DEBUG, TAG_STTC, "=====");
330         SLOG(LOG_DEBUG, TAG_STTC, " ");
331
332         return STT_ERROR_NONE;
333 }
334
335 int stt_destroy(stt_h stt)
336 {
337         stt_client_s* client = NULL;
338         if (0 != __stt_get_feature_enabled()) {
339                 return STT_ERROR_NOT_SUPPORTED;
340         }
341         if (0 != __stt_check_privilege()) {
342                 return STT_ERROR_PERMISSION_DENIED;
343         }
344         if (0 != __stt_check_handle(stt, &client)) {
345                 return STT_ERROR_INVALID_PARAMETER;
346         }
347
348         SLOG(LOG_DEBUG, TAG_STTC, "===== Destroy STT");
349
350         /* check used callback */
351         if (0 != stt_client_get_use_callback(client)) {
352                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Cannot destroy in Callback function");
353                 return STT_ERROR_OPERATION_FAILED;
354         }
355
356         stt_config_mgr_finalize(client->uid);
357
358         int ret = -1;
359
360         /* check state */
361         switch (client->current_state) {
362         case STT_STATE_PROCESSING:
363         case STT_STATE_RECORDING:
364         case STT_STATE_READY:
365                 ret = stt_dbus_request_finalize(client->uid);
366                 if (0 != ret) {
367                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request finalize : %s", __stt_get_error_code(ret));
368                 }
369         case STT_STATE_CREATED:
370                 if (NULL != g_connect_timer) {
371                         SLOG(LOG_DEBUG, TAG_STTC, "Connect Timer is deleted");
372                         ecore_timer_del(g_connect_timer);
373                         g_connect_timer = NULL;
374                 }
375
376                 /* Free resources */
377                 stt_client_destroy(stt);
378                 break;
379         default:
380                 break;
381         }
382
383         if (0 == stt_client_get_size()) {
384                 if (0 != stt_dbus_close_connection()) {
385                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to close connection");
386                 }
387         }
388
389         stt = NULL;
390
391         SLOG(LOG_DEBUG, TAG_STTC, "=====");
392         SLOG(LOG_DEBUG, TAG_STTC, " ");
393
394         return STT_ERROR_NONE;
395 }
396
397 bool __stt_config_supported_engine_cb(const char* engine_id, const char* engine_name,
398                                       const char* setting, bool support_silence, void* user_data)
399 {
400         stt_h stt = (stt_h)user_data;
401
402         stt_client_s* client = stt_client_get(stt);
403         if (NULL == client) {
404                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] A handle is not valid");
405                 return false;
406         }
407
408         /* call callback function */
409         if (NULL != client->supported_engine_cb) {
410                 return client->supported_engine_cb(stt, engine_id, engine_name, client->supported_engine_user_data);
411         } else {
412                 SLOG(LOG_WARN, TAG_STTC, "No registered callback function of supported engine");
413         }
414
415         return false;
416 }
417
418 int stt_foreach_supported_engines(stt_h stt, stt_supported_engine_cb callback, void* user_data)
419 {
420         stt_client_s* client = NULL;
421         if (0 != __stt_get_feature_enabled()) {
422                 return STT_ERROR_NOT_SUPPORTED;
423         }
424         if (0 != __stt_check_privilege()) {
425                 return STT_ERROR_PERMISSION_DENIED;
426         }
427         if (0 != __stt_check_handle(stt, &client)) {
428                 return STT_ERROR_INVALID_PARAMETER;
429         }
430
431         SLOG(LOG_DEBUG, TAG_STTC, "===== Foreach Supported engine");
432
433         if (NULL == callback) {
434                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
435                 return STT_ERROR_INVALID_PARAMETER;
436         }
437
438         if (client->current_state != STT_STATE_CREATED) {
439                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not CREATED", client->current_state);
440                 return STT_ERROR_INVALID_STATE;
441         }
442
443         client->supported_engine_cb = callback;
444         client->supported_engine_user_data = user_data;
445
446         int ret = 0;
447         ret = stt_config_mgr_get_engine_list(__stt_config_supported_engine_cb, client->stt);
448         ret = __stt_convert_config_error_code(ret);
449         if (0 != ret) {
450                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get engines : %s", __stt_get_error_code(ret));
451         }
452
453         client->supported_engine_cb = NULL;
454         client->supported_engine_user_data = NULL;
455
456         SLOG(LOG_DEBUG, TAG_STTC, "=====");
457         SLOG(LOG_DEBUG, TAG_STTC, " ");
458
459         return ret;
460 }
461
462 int stt_get_engine(stt_h stt, char** engine_id)
463 {
464         stt_client_s* client = NULL;
465         if (0 != __stt_get_feature_enabled()) {
466                 return STT_ERROR_NOT_SUPPORTED;
467         }
468         if (0 != __stt_check_privilege()) {
469                 return STT_ERROR_PERMISSION_DENIED;
470         }
471         if (0 != __stt_check_handle(stt, &client)) {
472                 return STT_ERROR_INVALID_PARAMETER;
473         }
474
475         SLOG(LOG_DEBUG, TAG_STTC, "===== Get current engine");
476
477         if (NULL == engine_id) {
478                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
479                 return STT_ERROR_INVALID_PARAMETER;
480         }
481
482         if (client->current_state != STT_STATE_CREATED) {
483                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not CREATED", client->current_state);
484                 return STT_ERROR_INVALID_STATE;
485         }
486
487         int ret = 0;
488
489         if (NULL != client->current_engine_id) {
490                 *engine_id = strdup(client->current_engine_id);
491                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current engine uuid = %s", *engine_id);
492         } else {
493
494                 ret = stt_config_mgr_get_engine(engine_id);
495                 ret = __stt_convert_config_error_code(ret);
496                 if (0 != ret) {
497                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request get current engine : %s", __stt_get_error_code(ret));
498                 } else {
499                         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current engine uuid = %s", *engine_id);
500                 }
501         }
502
503         SLOG(LOG_DEBUG, TAG_STTC, "=====");
504         SLOG(LOG_DEBUG, TAG_STTC, " ");
505
506         return ret;
507 }
508
509 int __stt_set_buxtonkey(const char* engine_id)
510 {
511         /* Set vconfkey */
512         struct buxton_client * bux_cli;
513         struct buxton_layer * bux_layer;
514         struct buxton_value * bux_val;
515
516         int ret = buxton_open(&bux_cli, NULL, NULL);
517         if (0 != ret) {
518                 SLOG(LOG_ERROR, stt_tag(), "[DBUS-BUXTON2] Fail to open buxton client");
519                 return STT_ERROR_OPERATION_FAILED;
520         }
521         SLOG(LOG_DEBUG, stt_tag(), "[DBUS-BUXTON2] buxton_open: %d", ret);
522         bux_layer = buxton_create_layer("system");
523         if (NULL == bux_layer) {
524                 SLOG(LOG_ERROR, stt_tag(), "[DBUS-BUXTON2] buxton_create_layer FAIL");
525                 buxton_close(bux_cli);
526                 bux_cli = NULL;
527                 return STT_ERROR_OPERATION_FAILED;
528         }
529         bux_val = buxton_value_create_string(engine_id);
530         if (NULL == bux_val) {
531                 SLOG(LOG_ERROR, stt_tag(), "[DBUS-BUXTON2] buxton_value_create_string FAIL");
532                 buxton_free_layer(bux_layer);
533                 buxton_close(bux_cli);
534                 bux_layer = NULL;
535                 bux_cli = NULL;
536                 return STT_ERROR_OPERATION_FAILED;
537         }
538
539         ret = buxton_set_value_sync(bux_cli, bux_layer, STT_ENGINE_DB_CUSTOM, bux_val);
540         if (0 != ret) {
541                 SLOG(LOG_ERROR, stt_tag(), "[DBUS-BUXTON2] Fail to set value sync");
542                 buxton_value_free(bux_val);
543                 buxton_free_layer(bux_layer);
544                 buxton_close(bux_cli);
545
546                 bux_cli = NULL;
547                 bux_layer = NULL;
548                 bux_val = NULL;
549                 return STT_ERROR_OPERATION_FAILED;
550         }
551         SLOG(LOG_DEBUG, stt_tag(), "[DBUS-BUXTON2] buxton_set_value_sync: %d, %s", ret, STT_ENGINE_DB_CUSTOM);
552
553         buxton_value_free(bux_val);
554         buxton_free_layer(bux_layer);
555         buxton_close(bux_cli);
556
557         bux_cli = NULL;
558         bux_layer = NULL;
559         bux_val = NULL;
560
561         return STT_ERROR_NONE;
562 }
563
564 int stt_set_engine(stt_h stt, const char* engine_id)
565 {
566         stt_client_s* client = NULL;
567         if (0 != __stt_get_feature_enabled()) {
568                 return STT_ERROR_NOT_SUPPORTED;
569         }
570         if (0 != __stt_check_privilege()) {
571                 return STT_ERROR_PERMISSION_DENIED;
572         }
573         if (0 != __stt_check_handle(stt, &client)) {
574                 return STT_ERROR_INVALID_PARAMETER;
575         }
576
577         SLOG(LOG_DEBUG, TAG_STTC, "===== Set current engine");
578
579         if (NULL == engine_id) {
580                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
581                 return STT_ERROR_INVALID_PARAMETER;
582         }
583
584         /* check state */
585         if (client->current_state != STT_STATE_CREATED) {
586                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not CREATED", client->current_state);
587                 return STT_ERROR_INVALID_STATE;
588         }
589
590         if (NULL != client->current_engine_id) {
591                 free(client->current_engine_id);
592                 client->current_engine_id = NULL;
593         }
594
595         SLOG(LOG_DEBUG, TAG_STTC, "===== engined_id(%s)", engine_id);
596
597         client->current_engine_id = strdup(engine_id);
598
599         /* Set vconfkey */
600         int ret = __stt_set_buxtonkey(engine_id);
601         if (0 != ret) {
602                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] set buxtonkey Failed!!!");
603                 return ret;
604         }
605
606         SLOG(LOG_DEBUG, TAG_STTC, "=====");
607         SLOG(LOG_DEBUG, TAG_STTC, " ");
608
609         return 0;
610 }
611
612 int stt_set_credential(stt_h stt, const char* credential)
613 {
614         stt_client_s* client = NULL;
615         if (0 != __stt_get_feature_enabled()) {
616                 return STT_ERROR_NOT_SUPPORTED;
617         }
618         if (0 != __stt_check_privilege()) {
619                 return STT_ERROR_PERMISSION_DENIED;
620         }
621         if (0 != __stt_check_handle(stt, &client)) {
622                 return STT_ERROR_INVALID_PARAMETER;
623         }
624
625         SLOG(LOG_DEBUG, TAG_STTC, "===== Set credential");
626
627         if (NULL == credential) {
628                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
629                 return STT_ERROR_INVALID_PARAMETER;
630         }
631
632         /* check state */
633         if (client->current_state != STT_STATE_CREATED && client->current_state != STT_STATE_READY) {
634                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not CREATED or READY", client->current_state);
635                 return STT_ERROR_INVALID_STATE;
636         }
637
638         if (NULL != client->credential) {
639                 free(client->credential);
640                 client->credential = NULL;
641         }
642         client->credential = strdup(credential);
643
644         SLOG(LOG_DEBUG, TAG_STTC, "=====");
645         SLOG(LOG_DEBUG, TAG_STTC, " ");
646
647         return STT_ERROR_NONE;
648 }
649
650 int stt_set_private_data(stt_h stt, const char* key, const char* data)
651 {
652         stt_client_s* client = NULL;
653         if (0 != __stt_get_feature_enabled()) {
654                 return STT_ERROR_NOT_SUPPORTED;
655         }
656         if (0 != __stt_check_privilege()) {
657                 return STT_ERROR_PERMISSION_DENIED;
658         }
659         if (0 != __stt_check_handle(stt, &client)) {
660                 return STT_ERROR_INVALID_PARAMETER;
661         }
662
663         SLOG(LOG_DEBUG, TAG_STTC, "===== Set private data");
664
665         if (NULL == key || NULL == data) {
666                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid parameter");
667                 return STT_ERROR_INVALID_PARAMETER;
668         }
669
670         /* check state */
671         if (STT_STATE_READY != client->current_state) {
672                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
673                 return STT_ERROR_INVALID_STATE;
674         }
675
676         int ret = -1;
677         int count = 0;
678         while (0 != ret) {
679                 ret = stt_dbus_request_set_private_data(client->uid, key, data);
680                 if (0 != ret) {
681                         if (STT_ERROR_TIMED_OUT != ret) {
682                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set private data : %s", __stt_get_error_code(ret));
683                                 return ret;
684                         } else {
685                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry : %s", __stt_get_error_code(ret));
686                                 usleep(10000);
687                                 count++;
688                                 if (STT_RETRY_COUNT == count) {
689                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
690                                         return ret;
691                                 }
692                         }
693                 }
694         }
695
696         SLOG(LOG_DEBUG, TAG_STTC, "=====");
697         SLOG(LOG_DEBUG, TAG_STTC, "");
698
699         return STT_ERROR_NONE;
700
701 }
702 int stt_get_private_data(stt_h stt, const char* key, char** data)
703 {
704         stt_client_s* client = NULL;
705         if (0 != __stt_get_feature_enabled()) {
706                 return STT_ERROR_NOT_SUPPORTED;
707         }
708         if (0 != __stt_check_privilege()) {
709                 return STT_ERROR_PERMISSION_DENIED;
710         }
711         if (0 != __stt_check_handle(stt, &client)) {
712                 return STT_ERROR_INVALID_PARAMETER;
713         }
714
715         SLOG(LOG_DEBUG, TAG_STTC, "===== Get private data");
716
717         if (NULL == key || NULL == data) {
718                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid parameter");
719                 return STT_ERROR_INVALID_PARAMETER;
720         }
721
722         /* check state */
723         if (STT_STATE_READY != client->current_state) {
724                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
725                 return STT_ERROR_INVALID_STATE;
726         }
727
728         int ret = -1;
729         int count = 0;
730         while (0 != ret) {
731                 ret = stt_dbus_request_get_private_data(client->uid, key, data);
732                 if (0 != ret) {
733                         if (STT_ERROR_TIMED_OUT != ret) {
734                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get private data : %s", __stt_get_error_code(ret));
735                                 return ret;
736                         } else {
737                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry : %s", __stt_get_error_code(ret));
738                                 usleep(10000);
739                                 count++;
740                                 if (STT_RETRY_COUNT == count) {
741                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
742                                         return ret;
743                                 }
744                         }
745                 }
746         }
747
748         if (0 == strncmp(*data, "NULL", strlen(*data))) {
749                 free(*data);
750                 *data = NULL;
751         }
752
753         SLOG(LOG_DEBUG, TAG_STTC, "=====");
754         SLOG(LOG_DEBUG, TAG_STTC, "");
755
756         return STT_ERROR_NONE;
757 }
758 static Eina_Bool __stt_connect_daemon(void *data)
759 {
760         stt_client_s* client = (stt_client_s*)data;
761
762         if (NULL == client) {
763                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
764                 g_connect_timer = NULL;
765                 return EINA_FALSE;
766         }
767
768         /* Send hello */
769         int ret = -1;
770         ret = stt_dbus_request_hello(client->uid);
771
772         if (0 != ret) {
773                 if (STT_ERROR_INVALID_STATE == ret) {
774                         g_connect_timer = NULL;
775                         return EINA_FALSE;
776                 }
777                 return EINA_TRUE;
778         }
779
780         g_connect_timer = NULL;
781         SLOG(LOG_DEBUG, TAG_STTC, "===== Connect stt-service");
782
783         /* request initialization */
784         bool silence_supported = false;
785         bool credential_needed = false;
786
787         ret = stt_dbus_request_initialize(client->uid, &silence_supported, &credential_needed);
788
789         if (STT_ERROR_ENGINE_NOT_FOUND == ret) {
790                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to initialize : %s", __stt_get_error_code(ret));
791
792                 client->reason = STT_ERROR_ENGINE_NOT_FOUND;
793                 ecore_timer_add(0, __stt_notify_error, (void*)client);
794
795                 return EINA_FALSE;
796
797         } else if (STT_ERROR_NONE != ret) {
798                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] Fail to connection. Retry to connect");
799                 return EINA_TRUE;
800         } else {
801                 /* success to connect stt-service */
802                 client->silence_supported = silence_supported;
803                 client->credential_needed = credential_needed;
804                 SLOG(LOG_DEBUG, TAG_STTC, "Supported options : silence(%s), credential(%s)", silence_supported ? "support" : "no support", credential_needed ? "need" : "no need");
805         }
806
807 #ifdef __UNUSED_CODES__
808         if (NULL != client->current_engine_id) {
809                 ret = -1;
810                 int count = 0;
811                 silence_supported = false;
812                 credential_needed = false;
813                 SLOG(LOG_DEBUG, TAG_STTC, "[WARNING] current_engine_id(%s)", client->current_engine_id);
814
815                 while (0 != ret) {
816                         ret = stt_dbus_request_set_current_engine(client->uid, client->current_engine_id, &silence_supported, &credential_needed);
817                         if (0 != ret) {
818                                 if (STT_ERROR_TIMED_OUT != ret) {
819                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set current engine : %s", __stt_get_error_code(ret));
820                                         return ret;
821                                 } else {
822                                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
823                                         usleep(10000);
824                                         count++;
825                                         if (STT_RETRY_COUNT == count) {
826                                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
827                                                 return ret;
828                                         }
829                                 }
830                         } else {
831                                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current engine uuid = %s", client->current_engine_id);
832
833                                 /* success to change engine */
834                                 client->silence_supported = silence_supported;
835                                 SLOG(LOG_DEBUG, TAG_STTC, "Supported options : silence(%s), credential(%s)", silence_supported ? "support" : "no support", credential_needed ? "need" : "no need");
836                         }
837                 }
838         }
839 #endif
840         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] uid(%d)", client->uid);
841
842         client->before_state = client->current_state;
843         client->current_state = STT_STATE_READY;
844
845         if (NULL != client->state_changed_cb) {
846                 stt_client_use_callback(client);
847                 client->state_changed_cb(client->stt, client->before_state,
848                         client->current_state, client->state_changed_user_data);
849                 stt_client_not_use_callback(client);
850                 SLOG(LOG_DEBUG, TAG_STTC, "State changed callback is called");
851         } else {
852                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
853         }
854
855         SLOG(LOG_DEBUG, TAG_STTC, "=====");
856         SLOG(LOG_DEBUG, TAG_STTC, "  ");
857
858         return EINA_FALSE;
859 }
860
861 int stt_prepare(stt_h stt)
862 {
863         stt_client_s* client = NULL;
864         if (0 != __stt_get_feature_enabled()) {
865                 return STT_ERROR_NOT_SUPPORTED;
866         }
867         if (0 != __stt_check_privilege()) {
868                 return STT_ERROR_PERMISSION_DENIED;
869         }
870         if (0 != __stt_check_handle(stt, &client)) {
871                 return STT_ERROR_INVALID_PARAMETER;
872         }
873
874         /* check state */
875         if (client->current_state != STT_STATE_CREATED) {
876                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not 'CREATED'", client->current_state);
877                 return STT_ERROR_INVALID_STATE;
878         }
879
880         g_connect_timer = ecore_timer_add(0, __stt_connect_daemon, (void*)client);
881
882         SLOG(LOG_DEBUG, TAG_STTC, "=====");
883         SLOG(LOG_DEBUG, TAG_STTC, " ");
884
885         return STT_ERROR_NONE;
886 }
887
888 int stt_unprepare(stt_h stt)
889 {
890         stt_client_s* client = NULL;
891         if (0 != __stt_get_feature_enabled()) {
892                 return STT_ERROR_NOT_SUPPORTED;
893         }
894         if (0 != __stt_check_privilege()) {
895                 return STT_ERROR_PERMISSION_DENIED;
896         }
897         if (0 != __stt_check_handle(stt, &client)) {
898                 return STT_ERROR_INVALID_PARAMETER;
899         }
900
901         SLOG(LOG_DEBUG, TAG_STTC, "===== Unprepare STT");
902
903         /* check state */
904         if (client->current_state != STT_STATE_READY) {
905                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not 'READY'", client->current_state);
906                 return STT_ERROR_INVALID_STATE;
907         }
908
909         int ret = -1;
910         int count = 0;
911         while (0 != ret) {
912                 ret = stt_dbus_request_finalize(client->uid);
913                 if (0 != ret) {
914                         if (STT_ERROR_TIMED_OUT != ret) {
915                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request finalize : %s", __stt_get_error_code(ret));
916                                 break;
917                         } else {
918                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
919                                 usleep(10000);
920                                 count++;
921                                 if (STT_RETRY_COUNT == count) {
922                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
923                                         break;
924                                 }
925                         }
926                 }
927         }
928
929         client->internal_state = STT_INTERNAL_STATE_NONE;
930
931         client->before_state = client->current_state;
932         client->current_state = STT_STATE_CREATED;
933
934         if (NULL != client->state_changed_cb) {
935                 stt_client_use_callback(client);
936                 client->state_changed_cb(client->stt, client->before_state,
937                         client->current_state, client->state_changed_user_data);
938                 stt_client_not_use_callback(client);
939         } else {
940                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
941         }
942
943         if (g_connect_timer) {
944                 ecore_timer_del(g_connect_timer);
945                 g_connect_timer = NULL;
946         }
947
948         SLOG(LOG_DEBUG, TAG_STTC, "=====");
949         SLOG(LOG_DEBUG, TAG_STTC, " ");
950
951         return STT_ERROR_NONE;
952 }
953
954 bool __stt_config_supported_language_cb(const char* engine_id, const char* language, void* user_data)
955 {
956         stt_h stt = (stt_h)user_data;
957
958         stt_client_s* client = stt_client_get(stt);
959         if (NULL == client) {
960                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] A handle is not valid");
961                 return false;
962         }
963
964         /* call callback function */
965         if (NULL != client->supported_lang_cb) {
966                 return client->supported_lang_cb(stt, language, client->supported_lang_user_data);
967         } else {
968                 SLOG(LOG_WARN, TAG_STTC, "No registered callback function of supported languages");
969         }
970
971         return false;
972 }
973
974 int stt_foreach_supported_languages(stt_h stt, stt_supported_language_cb callback, void* user_data)
975 {
976         stt_client_s* client = NULL;
977         if (0 != __stt_get_feature_enabled()) {
978                 return STT_ERROR_NOT_SUPPORTED;
979         }
980         if (0 != __stt_check_privilege()) {
981                 return STT_ERROR_PERMISSION_DENIED;
982         }
983         if (0 != __stt_check_handle(stt, &client)) {
984                 return STT_ERROR_INVALID_PARAMETER;
985         }
986
987         SLOG(LOG_DEBUG, TAG_STTC, "===== Foreach Supported Language");
988
989         if (NULL == callback) {
990                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
991                 return STT_ERROR_INVALID_PARAMETER;
992         }
993
994         int ret;
995         char* current_engine_id = NULL;
996
997         if (NULL == client->current_engine_id) {
998                 ret = stt_config_mgr_get_engine(&current_engine_id);
999                 ret = __stt_convert_config_error_code(ret);
1000                 if (0 != ret) {
1001                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get default engine id : %s", __stt_get_error_code(ret));
1002                         return ret;
1003                 }
1004         } else {
1005                 current_engine_id = strdup(client->current_engine_id);
1006                 if (NULL == current_engine_id) {
1007                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory");
1008                         return STT_ERROR_OUT_OF_MEMORY;
1009                 }
1010         }
1011
1012         client->supported_lang_cb = callback;
1013         client->supported_lang_user_data = user_data;
1014
1015         ret = stt_config_mgr_get_language_list(current_engine_id, __stt_config_supported_language_cb, client->stt);
1016         ret = __stt_convert_config_error_code(ret);
1017         if (0 != ret) {
1018                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get languages : %s", __stt_get_error_code(ret));
1019         }
1020
1021         if (NULL != current_engine_id) {
1022                 free(current_engine_id);
1023                 current_engine_id = NULL;
1024         }
1025
1026         client->supported_lang_cb = NULL;
1027         client->supported_lang_user_data = NULL;
1028
1029         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1030         SLOG(LOG_DEBUG, TAG_STTC, " ");
1031
1032         return ret;
1033 }
1034
1035 int stt_get_default_language(stt_h stt, char** language)
1036 {
1037         stt_client_s* client = NULL;
1038         if (0 != __stt_get_feature_enabled()) {
1039                 return STT_ERROR_NOT_SUPPORTED;
1040         }
1041         if (0 != __stt_check_privilege()) {
1042                 return STT_ERROR_PERMISSION_DENIED;
1043         }
1044         if (0 != __stt_check_handle(stt, &client)) {
1045                 return STT_ERROR_INVALID_PARAMETER;
1046         }
1047
1048         SLOG(LOG_DEBUG, TAG_STTC, "===== Get Default Language");
1049
1050         if (NULL == language) {
1051                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1052                 return STT_ERROR_INVALID_PARAMETER;
1053         }
1054
1055         int ret = 0;
1056         ret = stt_config_mgr_get_default_language(language);
1057         ret = __stt_convert_config_error_code(ret);
1058         if (0 != ret) {
1059                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get default language : %s", __stt_get_error_code(ret));
1060         } else {
1061                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current language = %s", *language);
1062         }
1063
1064         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1065         SLOG(LOG_DEBUG, TAG_STTC, " ");
1066
1067         return ret;
1068 }
1069
1070 int stt_get_state(stt_h stt, stt_state_e* state)
1071 {
1072         stt_client_s* client = NULL;
1073         if (0 != __stt_get_feature_enabled()) {
1074                 return STT_ERROR_NOT_SUPPORTED;
1075         }
1076         if (0 != __stt_check_privilege()) {
1077                 return STT_ERROR_PERMISSION_DENIED;
1078         }
1079         if (0 != __stt_check_handle(stt, &client)) {
1080                 return STT_ERROR_INVALID_PARAMETER;
1081         }
1082
1083         if (NULL == state) {
1084                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1085                 return STT_ERROR_INVALID_PARAMETER;
1086         }
1087
1088         *state = client->current_state;
1089
1090         switch (*state) {
1091         case STT_STATE_CREATED:         SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'CREATED'");        break;
1092         case STT_STATE_READY:           SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Ready'");          break;
1093         case STT_STATE_RECORDING:       SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Recording'");      break;
1094         case STT_STATE_PROCESSING:      SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Processing'");     break;
1095         default:                        SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid value");             break;
1096         }
1097
1098         return STT_ERROR_NONE;
1099 }
1100
1101 int stt_get_error_message(stt_h stt, char** err_msg)
1102 {
1103         stt_client_s* client = NULL;
1104         if (0 != __stt_get_feature_enabled()) {
1105                 return STT_ERROR_NOT_SUPPORTED;
1106         }
1107         if (0 != __stt_check_privilege()) {
1108                 return STT_ERROR_PERMISSION_DENIED;
1109         }
1110         if (0 != __stt_check_handle(stt, &client)) {
1111                 return STT_ERROR_INVALID_PARAMETER;
1112         }
1113
1114         if (NULL == err_msg) {
1115                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1116                 return STT_ERROR_INVALID_PARAMETER;
1117         }
1118
1119         if (false == g_err_callback_status) {
1120                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] This callback should be called during an err_callback");
1121                 return STT_ERROR_OPERATION_FAILED;
1122         }
1123
1124         if (NULL != client->err_msg) {
1125                 *err_msg = strdup(client->err_msg);
1126                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Error msg (%s)", *err_msg);
1127         } else {
1128                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Error msg (NULL)");
1129         }
1130
1131         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1132         SLOG(LOG_DEBUG, TAG_STTC, " ");
1133
1134         return STT_ERROR_NONE;
1135 }
1136
1137 int stt_is_recognition_type_supported(stt_h stt, const char* type, bool* support)
1138 {
1139         stt_client_s* client = NULL;
1140         if (0 != __stt_get_feature_enabled()) {
1141                 return STT_ERROR_NOT_SUPPORTED;
1142         }
1143         if (0 != __stt_check_privilege()) {
1144                 return STT_ERROR_PERMISSION_DENIED;
1145         }
1146         if (0 != __stt_check_handle(stt, &client)) {
1147                 return STT_ERROR_INVALID_PARAMETER;
1148         }
1149
1150         if (NULL == type || NULL == support) {
1151                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1152                 return STT_ERROR_INVALID_PARAMETER;
1153         }
1154
1155         /* check state */
1156         if (client->current_state != STT_STATE_READY) {
1157                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1158                 return STT_ERROR_INVALID_STATE;
1159         }
1160
1161         int ret = -1;
1162         int count = 0;
1163         while (0 != ret) {
1164                 ret = stt_dbus_request_is_recognition_type_supported(client->uid, type, support);
1165                 if (0 != ret) {
1166                         if (STT_ERROR_TIMED_OUT != ret) {
1167                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get recognition type supported : %s", __stt_get_error_code(ret));
1168                                 return ret;
1169                         } else {
1170                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1171                                 usleep(10000);
1172                                 count++;
1173                                 if (STT_RETRY_COUNT == count) {
1174                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1175                                         return ret;
1176                                 }
1177                         }
1178                 } else {
1179                         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] recognition type is %s", *support ? "true " : "false");
1180                         break;
1181                 }
1182         }
1183
1184         return STT_ERROR_NONE;
1185 }
1186
1187 int stt_set_silence_detection(stt_h stt, stt_option_silence_detection_e type)
1188 {
1189         stt_client_s* client = NULL;
1190         if (0 != __stt_get_feature_enabled()) {
1191                 return STT_ERROR_NOT_SUPPORTED;
1192         }
1193         if (0 != __stt_check_privilege()) {
1194                 return STT_ERROR_PERMISSION_DENIED;
1195         }
1196         if (0 != __stt_check_handle(stt, &client)) {
1197                 return STT_ERROR_INVALID_PARAMETER;
1198         }
1199
1200         /* check state */
1201         if (client->current_state != STT_STATE_READY) {
1202                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1203                 return STT_ERROR_INVALID_STATE;
1204         }
1205
1206         if (true == client->silence_supported) {
1207                 if (type >= STT_OPTION_SILENCE_DETECTION_FALSE && type <= STT_OPTION_SILENCE_DETECTION_AUTO) {
1208                         client->silence = type;
1209                 } else {
1210                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Type is invalid");
1211                         return STT_ERROR_INVALID_PARAMETER;
1212                 }
1213         } else {
1214                 return STT_ERROR_NOT_SUPPORTED_FEATURE;
1215         }
1216
1217         return STT_ERROR_NONE;
1218 }
1219
1220 int stt_set_start_sound(stt_h stt, const char* filename)
1221 {
1222         stt_client_s* client = NULL;
1223         if (0 != __stt_get_feature_enabled()) {
1224                 return STT_ERROR_NOT_SUPPORTED;
1225         }
1226         if (0 != __stt_check_privilege()) {
1227                 return STT_ERROR_PERMISSION_DENIED;
1228         }
1229         if (0 != __stt_check_handle(stt, &client)) {
1230                 return STT_ERROR_INVALID_PARAMETER;
1231         }
1232
1233         SLOG(LOG_DEBUG, TAG_STTC, "===== STT SET START SOUND");
1234
1235         if (NULL == filename) {
1236                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1237                 return STT_ERROR_INVALID_PARAMETER;
1238         }
1239
1240         if (0 != access(filename, F_OK)) {
1241                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] File does not exist");
1242                 return STT_ERROR_INVALID_PARAMETER;
1243         }
1244
1245         /* check state */
1246         if (client->current_state != STT_STATE_READY) {
1247                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1248                 return STT_ERROR_INVALID_STATE;
1249         }
1250
1251         int ret = -1;
1252         int count = 0;
1253         while (0 != ret) {
1254                 ret = stt_dbus_request_set_start_sound(client->uid, filename);
1255                 if (0 != ret) {
1256                         if (STT_ERROR_TIMED_OUT != ret) {
1257                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set start sound : %s", __stt_get_error_code(ret));
1258                                 return ret;
1259                         } else {
1260                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1261                                 usleep(10000);
1262                                 count++;
1263                                 if (STT_RETRY_COUNT == count) {
1264                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1265                                         return ret;
1266                                 }
1267                         }
1268                 } else {
1269                         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Set start sound : %s", filename);
1270                         break;
1271                 }
1272         }
1273
1274         return STT_ERROR_NONE;
1275 }
1276
1277 int stt_unset_start_sound(stt_h stt)
1278 {
1279         stt_client_s* client = NULL;
1280         if (0 != __stt_get_feature_enabled()) {
1281                 return STT_ERROR_NOT_SUPPORTED;
1282         }
1283         if (0 != __stt_check_privilege()) {
1284                 return STT_ERROR_PERMISSION_DENIED;
1285         }
1286         if (0 != __stt_check_handle(stt, &client)) {
1287                 return STT_ERROR_INVALID_PARAMETER;
1288         }
1289
1290         SLOG(LOG_DEBUG, TAG_STTC, "===== STT UNSET START SOUND");
1291
1292         /* check state */
1293         if (client->current_state != STT_STATE_READY) {
1294                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1295                 return STT_ERROR_INVALID_STATE;
1296         }
1297
1298         int ret = -1;
1299         int count = 0;
1300         while (0 != ret) {
1301                 ret = stt_dbus_request_unset_start_sound(client->uid);
1302                 if (0 != ret) {
1303                         if (STT_ERROR_TIMED_OUT != ret) {
1304                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to unset start sound : %s", __stt_get_error_code(ret));
1305                                 return ret;
1306                         } else {
1307                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1308                                 usleep(10000);
1309                                 count++;
1310                                 if (STT_RETRY_COUNT == count) {
1311                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1312                                         return ret;
1313                                 }
1314                         }
1315                 } else {
1316                         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Unset start sound");
1317                         break;
1318                 }
1319         }
1320
1321         return STT_ERROR_NONE;
1322 }
1323
1324 int stt_set_stop_sound(stt_h stt, const char* filename)
1325 {
1326         stt_client_s* client = NULL;
1327         if (0 != __stt_get_feature_enabled()) {
1328                 return STT_ERROR_NOT_SUPPORTED;
1329         }
1330         if (0 != __stt_check_privilege()) {
1331                 return STT_ERROR_PERMISSION_DENIED;
1332         }
1333         if (0 != __stt_check_handle(stt, &client)) {
1334                 return STT_ERROR_INVALID_PARAMETER;
1335         }
1336
1337         SLOG(LOG_DEBUG, TAG_STTC, "===== STT SET STOP SOUND");
1338
1339         if (NULL == filename) {
1340                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1341                 return STT_ERROR_INVALID_PARAMETER;
1342         }
1343
1344         if (0 != access(filename, F_OK)) {
1345                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] File does not exist");
1346                 return STT_ERROR_INVALID_PARAMETER;
1347         }
1348
1349         /* check state */
1350         if (client->current_state != STT_STATE_READY) {
1351                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1352                 return STT_ERROR_INVALID_STATE;
1353         }
1354
1355         int ret = -1;
1356         int count = 0;
1357         while (0 != ret) {
1358                 ret = stt_dbus_request_set_stop_sound(client->uid, filename);
1359                 if (0 != ret) {
1360                         if (STT_ERROR_TIMED_OUT != ret) {
1361                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set stop sound : %s", __stt_get_error_code(ret));
1362                                 return ret;
1363                         } else {
1364                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1365                                 usleep(10000);
1366                                 count++;
1367                                 if (STT_RETRY_COUNT == count) {
1368                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1369                                         return ret;
1370                                 }
1371                         }
1372                 } else {
1373                         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Set stop sound : %s", filename);
1374                         break;
1375                 }
1376         }
1377
1378         return STT_ERROR_NONE;
1379 }
1380
1381 int stt_unset_stop_sound(stt_h stt)
1382 {
1383         stt_client_s* client = NULL;
1384         if (0 != __stt_get_feature_enabled()) {
1385                 return STT_ERROR_NOT_SUPPORTED;
1386         }
1387         if (0 != __stt_check_privilege()) {
1388                 return STT_ERROR_PERMISSION_DENIED;
1389         }
1390         if (0 != __stt_check_handle(stt, &client)) {
1391                 return STT_ERROR_INVALID_PARAMETER;
1392         }
1393
1394         SLOG(LOG_DEBUG, TAG_STTC, "===== STT UNSET STOP SOUND");
1395
1396         /* check state */
1397         if (client->current_state != STT_STATE_READY) {
1398                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1399                 return STT_ERROR_INVALID_STATE;
1400         }
1401
1402         int ret = -1;
1403         int count = 0;
1404         while (0 != ret) {
1405                 ret = stt_dbus_request_unset_stop_sound(client->uid);
1406                 if (0 != ret) {
1407                         if (STT_ERROR_TIMED_OUT != ret) {
1408                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to unset stop sound : %s", __stt_get_error_code(ret));
1409                                 return ret;
1410                         } else {
1411                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1412                                 usleep(10000);
1413                                 count++;
1414                                 if (STT_RETRY_COUNT == count) {
1415                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1416                                         return ret;
1417                                 }
1418                         }
1419                 } else {
1420                         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Unset stop sound");
1421                         break;
1422                 }
1423         }
1424
1425         return STT_ERROR_NONE;
1426 }
1427
1428 int stt_start(stt_h stt, const char* language, const char* type)
1429 {
1430         stt_client_s* client = NULL;
1431         if (0 != __stt_get_feature_enabled()) {
1432                 return STT_ERROR_NOT_SUPPORTED;
1433         }
1434         if (0 != __stt_check_privilege()) {
1435                 return STT_ERROR_PERMISSION_DENIED;
1436         }
1437         if (0 != __stt_check_handle(stt, &client)) {
1438                 return STT_ERROR_INVALID_PARAMETER;
1439         }
1440
1441         SLOG(LOG_DEBUG, TAG_STTC, "===== STT START");
1442
1443         /* check state */
1444         if (client->current_state != STT_STATE_READY) {
1445                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1446                 return STT_ERROR_INVALID_STATE;
1447         }
1448
1449         if (STT_INTERNAL_STATE_NONE != client->internal_state) {
1450                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is NOT none : %d", client->internal_state);
1451                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
1452         }
1453
1454         int ret = -1;
1455         char appid[128] = {0, };
1456         ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
1457
1458         if ((AUL_R_OK != ret) || (0 == strlen(appid))) {
1459                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get application ID");
1460         } else {
1461                 SLOG(LOG_DEBUG, TAG_STTC, "[DEBUG] Current app id is %s", appid);
1462         }
1463
1464         char* temp = NULL;
1465         if (NULL == language) {
1466                 temp = strdup("default");
1467         } else {
1468                 temp = strdup(language);
1469         }
1470
1471         if (true == client->credential_needed && NULL == client->credential) {
1472                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Do not have app credential for this engine(%s)", client->current_engine_id);
1473                 return STT_ERROR_PERMISSION_DENIED;
1474         }
1475
1476         ret = stt_dbus_request_start(client->uid, temp, type, client->silence, appid, client->credential);
1477         if (0 != ret) {
1478                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to start : %s", __stt_get_error_code(ret));
1479         } else {
1480                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Start is successful but not done");
1481                 client->internal_state = STT_INTERNAL_STATE_STARTING;
1482         }
1483
1484         if (NULL != temp)       free(temp);
1485
1486         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1487         SLOG(LOG_DEBUG, TAG_STTC, " ");
1488
1489         return ret;
1490 }
1491
1492 int stt_stop(stt_h stt)
1493 {
1494         stt_client_s* client = NULL;
1495         if (0 != __stt_get_feature_enabled()) {
1496                 return STT_ERROR_NOT_SUPPORTED;
1497         }
1498         if (0 != __stt_check_privilege()) {
1499                 return STT_ERROR_PERMISSION_DENIED;
1500         }
1501         if (0 != __stt_check_handle(stt, &client)) {
1502                 return STT_ERROR_INVALID_PARAMETER;
1503         }
1504
1505         SLOG(LOG_DEBUG, TAG_STTC, "===== STT STOP");
1506
1507         /* check state */
1508         if (client->current_state != STT_STATE_RECORDING) {
1509                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Current state(%d) is NOT RECORDING", client->current_state);
1510                 return STT_ERROR_INVALID_STATE;
1511         }
1512
1513         if (STT_INTERNAL_STATE_STARTING == client->internal_state) {
1514                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STARTING : %d", client->internal_state);
1515                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
1516         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state) {
1517                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is CANCELING : %d", client->internal_state);
1518                 return STT_ERROR_IN_PROGRESS_TO_READY;
1519         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state) {
1520                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STOPPING : %d", client->internal_state);
1521                 return STT_ERROR_IN_PROGRESS_TO_PROCESSING;
1522         }
1523
1524         int ret = stt_dbus_request_stop(client->uid);
1525
1526         if (0 != ret) {
1527                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to stop : %s", __stt_get_error_code(ret));
1528         } else {
1529                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Stop is successful but not done");
1530                 client->internal_state = STT_INTERNAL_STATE_STOPPING;
1531         }
1532
1533         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1534         SLOG(LOG_DEBUG, TAG_STTC, " ");
1535
1536         return ret;
1537 }
1538
1539
1540 int stt_cancel(stt_h stt)
1541 {
1542         stt_client_s* client = NULL;
1543         if (0 != __stt_get_feature_enabled()) {
1544                 return STT_ERROR_NOT_SUPPORTED;
1545         }
1546         if (0 != __stt_check_privilege()) {
1547                 return STT_ERROR_PERMISSION_DENIED;
1548         }
1549         if (0 != __stt_check_handle(stt, &client)) {
1550                 return STT_ERROR_INVALID_PARAMETER;
1551         }
1552
1553         SLOG(LOG_DEBUG, TAG_STTC, "===== STT CANCEL");
1554
1555         /* check state */
1556         if (STT_STATE_RECORDING != client->current_state && STT_STATE_PROCESSING != client->current_state) {
1557                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid state : Current state(%d) is 'Ready'", client->current_state);
1558                 return STT_ERROR_INVALID_STATE;
1559         }
1560
1561         if (STT_INTERNAL_STATE_STARTING == client->internal_state) {
1562                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STARTING : %d", client->internal_state);
1563                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
1564         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state) {
1565                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STOPPING : %d", client->internal_state);
1566                 return STT_ERROR_IN_PROGRESS_TO_PROCESSING;
1567         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state) {
1568                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is CANCELING : %d", client->internal_state);
1569                 return STT_ERROR_IN_PROGRESS_TO_READY;
1570         }
1571
1572         int ret = stt_dbus_request_cancel(client->uid);
1573         if (0 != ret) {
1574                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to cancel : %s", __stt_get_error_code(ret));
1575         } else {
1576                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Cancel is successful but not done");
1577                 client->internal_state = STT_INTERNAL_STATE_CANCELING;
1578         }
1579
1580         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1581         SLOG(LOG_DEBUG, TAG_STTC, " ");
1582
1583         return ret;
1584 }
1585
1586 int __stt_cb_set_volume(int uid, float volume)
1587 {
1588         stt_client_s* client = NULL;
1589
1590         client = stt_client_get_by_uid(uid);
1591         if (NULL == client) {
1592                 SLOG(LOG_ERROR, TAG_STTC, "Handle is NOT valid");
1593                 return STT_ERROR_INVALID_PARAMETER;
1594         }
1595
1596         if (STT_STATE_RECORDING != client->current_state) {
1597                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Invalid state : NO 'Recording' state, cur(%d)", client->current_state);
1598                 return STT_ERROR_INVALID_STATE;
1599         }
1600
1601         g_volume_db = volume;
1602         SLOG(LOG_DEBUG, TAG_STTC, "Set volume (%f)", g_volume_db);
1603
1604         return 0;
1605 }
1606
1607 int stt_get_recording_volume(stt_h stt, float* volume)
1608 {
1609         stt_client_s* client = NULL;
1610         if (0 != __stt_get_feature_enabled()) {
1611                 return STT_ERROR_NOT_SUPPORTED;
1612         }
1613         if (0 != __stt_check_privilege()) {
1614                 return STT_ERROR_PERMISSION_DENIED;
1615         }
1616         if (0 != __stt_check_handle(stt, &client)) {
1617                 return STT_ERROR_INVALID_PARAMETER;
1618         }
1619
1620         if (NULL == volume) {
1621                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1622                 return STT_ERROR_INVALID_PARAMETER;
1623         }
1624
1625         if (STT_STATE_RECORDING != client->current_state) {
1626                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Invalid state : NO 'Recording' state, cur(%d)", client->current_state);
1627                 return STT_ERROR_INVALID_STATE;
1628         }
1629
1630         *volume = g_volume_db;
1631
1632         return STT_ERROR_NONE;
1633 }
1634
1635 bool __stt_result_time_cb(int index, int event, const char* text, long start_time, long end_time, void* user_data)
1636 {
1637         stt_client_s* client = (stt_client_s*)user_data;
1638
1639         /* check handle */
1640         if (NULL == client) {
1641                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
1642                 return EINA_FALSE;
1643         }
1644
1645         if (NULL != client->result_time_cb) {
1646                 SLOG(LOG_DEBUG, TAG_STTC, "(%d) event(%d) text(%s) start(%ld) end(%ld)",
1647                         index, event, text, start_time, end_time);
1648                 client->result_time_cb(client->stt, index, (stt_result_time_event_e)event,
1649                         text, start_time, end_time, client->result_time_user_data);
1650         } else {
1651                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Callback is NULL");
1652                 return false;
1653         }
1654
1655         return true;
1656 }
1657
1658 int stt_foreach_detailed_result(stt_h stt, stt_result_time_cb callback, void* user_data)
1659 {
1660         stt_client_s* client = NULL;
1661         if (0 != __stt_get_feature_enabled()) {
1662                 return STT_ERROR_NOT_SUPPORTED;
1663         }
1664         if (0 != __stt_check_privilege()) {
1665                 return STT_ERROR_PERMISSION_DENIED;
1666         }
1667         if (0 != __stt_check_handle(stt, &client)) {
1668                 return STT_ERROR_INVALID_PARAMETER;
1669         }
1670
1671         SLOG(LOG_DEBUG, TAG_STTC, "===== STT FOREACH DETAILED RESULT");
1672
1673         if (NULL == callback) {
1674                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1675                 return STT_ERROR_INVALID_PARAMETER;
1676         }
1677
1678         client->result_time_cb = callback;
1679         client->result_time_user_data = user_data;
1680
1681         int ret = -1;
1682         ret = stt_config_mgr_foreach_time_info(__stt_result_time_cb, client);
1683         ret = __stt_convert_config_error_code(ret);
1684         if (0 != ret) {
1685                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to foreach time info : %s", __stt_get_error_code(ret));
1686         }
1687
1688         client->result_time_cb = NULL;
1689         client->result_time_user_data = NULL;
1690
1691         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1692         SLOG(LOG_DEBUG, TAG_STTC, " ");
1693
1694         return ret;
1695 }
1696
1697 static Eina_Bool __stt_notify_error(void *data)
1698 {
1699         stt_client_s* client = (stt_client_s*)data;
1700
1701         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error from sttd");
1702
1703         /* check handle */
1704         if (NULL == client) {
1705                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
1706                 return EINA_FALSE;
1707         }
1708
1709         if (NULL == stt_client_get_by_uid(client->uid))
1710                 return EINA_FALSE;
1711
1712         if (NULL != client->error_cb) {
1713                 stt_client_use_callback(client);
1714                 g_err_callback_status = true;
1715                 client->error_cb(client->stt, client->reason, client->error_user_data);
1716                 g_err_callback_status = false;
1717                 stt_client_not_use_callback(client);
1718                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is called : reason [%d]", client->reason);
1719         } else {
1720                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null");
1721         }
1722
1723         return EINA_FALSE;
1724 }
1725
1726 int __stt_cb_error(int uid, int reason, char* err_msg)
1727 {
1728         stt_client_s* client = stt_client_get_by_uid(uid);
1729         if (NULL == client) {
1730                 SLOG(LOG_ERROR, TAG_STTC, "Handle not found");
1731                 return -1;
1732         }
1733
1734         client->reason = reason;
1735         client->internal_state = STT_INTERNAL_STATE_NONE;
1736         if (NULL != client->err_msg) {
1737                 free(client->err_msg);
1738                 client->err_msg = NULL;
1739         }
1740         client->err_msg = strdup(err_msg);
1741
1742         SLOG(LOG_INFO, TAG_STTC, "internal state is initialized to 0");
1743
1744         if (NULL != client->error_cb) {
1745                 ecore_timer_add(0, __stt_notify_error, client);
1746         } else {
1747                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null");
1748         }
1749
1750         if (STT_ERROR_SERVICE_RESET == reason) {
1751                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Service reset");
1752
1753                 client->current_state = STT_STATE_CREATED;
1754                 if (0 != stt_prepare(client->stt)) {
1755                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare");
1756                 }
1757         }
1758
1759         return 0;
1760 }
1761
1762 static void __stt_notify_state_changed(void *data)
1763 {
1764         stt_client_s* client = (stt_client_s*)data;
1765
1766         /* check handle */
1767         if (NULL == client) {
1768                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
1769                 return;
1770         }
1771
1772         if (NULL == stt_client_get_by_uid(client->uid)) {
1773                 return;
1774         }
1775
1776         if (STT_INTERNAL_STATE_STARTING == client->internal_state && STT_STATE_RECORDING == client->current_state) {
1777                 client->internal_state = STT_INTERNAL_STATE_NONE;
1778                 SLOG(LOG_DEBUG, TAG_STTC, "Internal state change to NONE");
1779         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state && STT_STATE_PROCESSING == client->current_state) {
1780                 client->internal_state = STT_INTERNAL_STATE_NONE;
1781                 SLOG(LOG_DEBUG, TAG_STTC, "Internal state change to NONE");
1782         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state && STT_STATE_READY == client->current_state) {
1783                 client->internal_state = STT_INTERNAL_STATE_NONE;
1784                 SLOG(LOG_DEBUG, TAG_STTC, "Internal state change to NONE");
1785         }
1786
1787         if (NULL != client->state_changed_cb) {
1788                 stt_client_use_callback(client);
1789                 client->state_changed_cb(client->stt, client->before_state,
1790                         client->current_state, client->state_changed_user_data);
1791                 stt_client_not_use_callback(client);
1792                 SLOG(LOG_DEBUG, TAG_STTC, "State changed callback is called");
1793         } else {
1794                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
1795         }
1796
1797         return;
1798 }
1799
1800 static Eina_Bool __stt_notify_result(void *data)
1801 {
1802         stt_client_s* client = (stt_client_s*)data;
1803
1804         /* check handle */
1805         if (NULL == client) {
1806                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
1807                 return EINA_FALSE;
1808         }
1809
1810         if (NULL == stt_client_get_by_uid(client->uid)) {
1811                 return EINA_FALSE;
1812         }
1813
1814         if (NULL != client->recognition_result_cb) {
1815                 stt_client_use_callback(client);
1816                 client->recognition_result_cb(client->stt, client->event, (const char**)client->data_list, client->data_count,
1817                         client->msg, client->recognition_result_user_data);
1818                 stt_client_not_use_callback(client);
1819                 SLOG(LOG_DEBUG, TAG_STTC, "client recognition result callback called");
1820         } else {
1821                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] User recognition result callback is NULL");
1822         }
1823
1824         if (NULL != client->msg) {
1825                 free(client->msg);
1826                 client->msg = NULL;
1827         }
1828
1829         if (NULL != client->data_list) {
1830                 char **temp = NULL;
1831                 temp = client->data_list;
1832
1833                 int i = 0;
1834                 for (i = 0; i < client->data_count; i++) {
1835                         if (NULL != temp[i]) {
1836                                 free(temp[i]);
1837                                 temp[i] = NULL;
1838                         } else {
1839                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Result data is error");
1840                         }
1841                 }
1842                 free(client->data_list);
1843                 client->data_list = NULL;
1844         }
1845
1846         client->data_count = 0;
1847
1848         stt_config_mgr_remove_time_info_file();
1849
1850         if (STT_RESULT_EVENT_FINAL_RESULT == client->event || STT_RESULT_EVENT_ERROR == client->event) {
1851                 client->before_state = client->current_state;
1852                 client->current_state = STT_STATE_READY;
1853
1854                 if (NULL != client->state_changed_cb) {
1855                         ecore_main_loop_thread_safe_call_async(__stt_notify_state_changed, client);
1856                 } else {
1857                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
1858                 }
1859         }
1860
1861         return EINA_FALSE;
1862 }
1863
1864 int __stt_cb_result(int uid, int event, char** data, int data_count, const char* msg)
1865 {
1866         stt_client_s* client = NULL;
1867
1868         client = stt_client_get_by_uid(uid);
1869         if (NULL == client) {
1870                 SLOG(LOG_ERROR, TAG_STTC, "Handle is NOT valid");
1871                 return STT_ERROR_INVALID_PARAMETER;
1872         }
1873
1874         if (NULL != msg)
1875                 SLOG(LOG_DEBUG, TAG_STTC, "Recognition Result Message = %s", msg);
1876
1877         int i = 0;
1878         for (i = 0; i < data_count; i++) {
1879                 if (NULL != data[i])
1880                         SLOG(LOG_DEBUG, TAG_STTC, "Recognition Result[%d] = %s", i, data[i]);
1881         }
1882
1883         if (NULL != client->recognition_result_cb) {
1884                 client->event = event;
1885                 if (NULL != msg) {
1886                         client->msg = strdup(msg);
1887                 }
1888
1889                 client->data_count = data_count;
1890
1891                 if (data_count > 0) {
1892                         char **temp = NULL;
1893                         temp = (char**)calloc(data_count, sizeof(char*));
1894                         if (NULL == temp) {
1895                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory");
1896                                 return STT_ERROR_OUT_OF_MEMORY;
1897                         }
1898
1899                         for (i = 0; i < data_count; i++) {
1900                                 if (NULL != data[i])
1901                                         temp[i] = strdup(data[i]);
1902                                 else
1903                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Result data is error");
1904                         }
1905
1906                         client->data_list = temp;
1907                 }
1908         } else {
1909                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] User result callback is null");
1910         }
1911
1912         ecore_timer_add(0, __stt_notify_result, client);
1913
1914         return STT_ERROR_NONE;
1915 }
1916
1917 int __stt_cb_set_state(int uid, int state)
1918 {
1919         stt_client_s* client = stt_client_get_by_uid(uid);
1920         if (NULL == client) {
1921                 SLOG(LOG_ERROR, TAG_STTC, "Handle not found");
1922                 return -1;
1923         }
1924
1925         stt_state_e state_from_daemon = (stt_state_e)state;
1926
1927         if (client->current_state == state_from_daemon) {
1928                 SLOG(LOG_DEBUG, TAG_STTC, "Current state has already been %d", client->current_state);
1929                 return 0;
1930         }
1931
1932         client->before_state = client->current_state;
1933         client->current_state = state_from_daemon;
1934
1935         ecore_main_loop_thread_safe_call_async(__stt_notify_state_changed, client);
1936         return 0;
1937 }
1938
1939 int stt_set_recognition_result_cb(stt_h stt, stt_recognition_result_cb callback, void* user_data)
1940 {
1941         stt_client_s* client = NULL;
1942         if (0 != __stt_get_feature_enabled()) {
1943                 return STT_ERROR_NOT_SUPPORTED;
1944         }
1945         if (0 != __stt_check_privilege()) {
1946                 return STT_ERROR_PERMISSION_DENIED;
1947         }
1948         if (0 != __stt_check_handle(stt, &client)) {
1949                 return STT_ERROR_INVALID_PARAMETER;
1950         }
1951
1952         if (callback == NULL)
1953                 return STT_ERROR_INVALID_PARAMETER;
1954
1955         if (STT_STATE_CREATED != client->current_state) {
1956                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
1957                 return STT_ERROR_INVALID_STATE;
1958         }
1959
1960         client->recognition_result_cb = callback;
1961         client->recognition_result_user_data = user_data;
1962
1963         return 0;
1964 }
1965
1966 int stt_unset_recognition_result_cb(stt_h stt)
1967 {
1968         stt_client_s* client = NULL;
1969         if (0 != __stt_get_feature_enabled()) {
1970                 return STT_ERROR_NOT_SUPPORTED;
1971         }
1972         if (0 != __stt_check_privilege()) {
1973                 return STT_ERROR_PERMISSION_DENIED;
1974         }
1975         if (0 != __stt_check_handle(stt, &client)) {
1976                 return STT_ERROR_INVALID_PARAMETER;
1977         }
1978
1979         if (STT_STATE_CREATED != client->current_state) {
1980                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
1981                 return STT_ERROR_INVALID_STATE;
1982         }
1983
1984         client->recognition_result_cb = NULL;
1985         client->recognition_result_user_data = NULL;
1986
1987         return 0;
1988 }
1989
1990 int stt_set_state_changed_cb(stt_h stt, stt_state_changed_cb callback, void* user_data)
1991 {
1992         stt_client_s* client = NULL;
1993         if (0 != __stt_get_feature_enabled()) {
1994                 return STT_ERROR_NOT_SUPPORTED;
1995         }
1996         if (0 != __stt_check_privilege()) {
1997                 return STT_ERROR_PERMISSION_DENIED;
1998         }
1999         if (0 != __stt_check_handle(stt, &client)) {
2000                 return STT_ERROR_INVALID_PARAMETER;
2001         }
2002
2003         if (NULL == callback)
2004                 return STT_ERROR_INVALID_PARAMETER;
2005
2006         if (STT_STATE_CREATED != client->current_state) {
2007                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2008                 return STT_ERROR_INVALID_STATE;
2009         }
2010
2011         client->state_changed_cb = callback;
2012         client->state_changed_user_data = user_data;
2013
2014         return 0;
2015 }
2016
2017 int stt_unset_state_changed_cb(stt_h stt)
2018 {
2019         stt_client_s* client = NULL;
2020         if (0 != __stt_get_feature_enabled()) {
2021                 return STT_ERROR_NOT_SUPPORTED;
2022         }
2023         if (0 != __stt_check_privilege()) {
2024                 return STT_ERROR_PERMISSION_DENIED;
2025         }
2026         if (0 != __stt_check_handle(stt, &client)) {
2027                 return STT_ERROR_INVALID_PARAMETER;
2028         }
2029
2030         if (STT_STATE_CREATED != client->current_state) {
2031                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2032                 return STT_ERROR_INVALID_STATE;
2033         }
2034
2035         client->state_changed_cb = NULL;
2036         client->state_changed_user_data = NULL;
2037
2038         return 0;
2039 }
2040
2041 int stt_set_error_cb(stt_h stt, stt_error_cb callback, void* user_data)
2042 {
2043         stt_client_s* client = NULL;
2044         if (0 != __stt_get_feature_enabled()) {
2045                 return STT_ERROR_NOT_SUPPORTED;
2046         }
2047         if (0 != __stt_check_privilege()) {
2048                 return STT_ERROR_PERMISSION_DENIED;
2049         }
2050         if (0 != __stt_check_handle(stt, &client)) {
2051                 return STT_ERROR_INVALID_PARAMETER;
2052         }
2053
2054         if (NULL == callback)
2055                 return STT_ERROR_INVALID_PARAMETER;
2056
2057         if (STT_STATE_CREATED != client->current_state) {
2058                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2059                 return STT_ERROR_INVALID_STATE;
2060         }
2061
2062         client->error_cb = callback;
2063         client->error_user_data = user_data;
2064
2065         return 0;
2066 }
2067
2068 int stt_unset_error_cb(stt_h stt)
2069 {
2070         stt_client_s* client = NULL;
2071         if (0 != __stt_get_feature_enabled()) {
2072                 return STT_ERROR_NOT_SUPPORTED;
2073         }
2074         if (0 != __stt_check_privilege()) {
2075                 return STT_ERROR_PERMISSION_DENIED;
2076         }
2077         if (0 != __stt_check_handle(stt, &client)) {
2078                 return STT_ERROR_INVALID_PARAMETER;
2079         }
2080
2081         if (STT_STATE_CREATED != client->current_state) {
2082                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2083                 return STT_ERROR_INVALID_STATE;
2084         }
2085
2086         client->error_cb = NULL;
2087         client->error_user_data = NULL;
2088
2089         return 0;
2090 }
2091
2092 int stt_set_default_language_changed_cb(stt_h stt, stt_default_language_changed_cb callback, void* user_data)
2093 {
2094         stt_client_s* client = NULL;
2095         if (0 != __stt_get_feature_enabled()) {
2096                 return STT_ERROR_NOT_SUPPORTED;
2097         }
2098         if (0 != __stt_check_privilege()) {
2099                 return STT_ERROR_PERMISSION_DENIED;
2100         }
2101         if (0 != __stt_check_handle(stt, &client)) {
2102                 return STT_ERROR_INVALID_PARAMETER;
2103         }
2104
2105         if (NULL == callback)
2106                 return STT_ERROR_INVALID_PARAMETER;
2107
2108         if (STT_STATE_CREATED != client->current_state) {
2109                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2110                 return STT_ERROR_INVALID_STATE;
2111         }
2112
2113         client->default_lang_changed_cb = callback;
2114         client->default_lang_changed_user_data = user_data;
2115
2116         return 0;
2117 }
2118
2119 int stt_unset_default_language_changed_cb(stt_h stt)
2120 {
2121         stt_client_s* client = NULL;
2122         if (0 != __stt_get_feature_enabled()) {
2123                 return STT_ERROR_NOT_SUPPORTED;
2124         }
2125         if (0 != __stt_check_privilege()) {
2126                 return STT_ERROR_PERMISSION_DENIED;
2127         }
2128         if (0 != __stt_check_handle(stt, &client)) {
2129                 return STT_ERROR_INVALID_PARAMETER;
2130         }
2131
2132         if (STT_STATE_CREATED != client->current_state) {
2133                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2134                 return STT_ERROR_INVALID_STATE;
2135         }
2136
2137         client->default_lang_changed_cb = NULL;
2138         client->default_lang_changed_user_data = NULL;
2139
2140         return 0;
2141 }
2142
2143 int stt_set_engine_changed_cb(stt_h stt, stt_engine_changed_cb callback, void* user_data)
2144 {
2145         stt_client_s* client = NULL;
2146         if (0 != __stt_get_feature_enabled()) {
2147                 return STT_ERROR_NOT_SUPPORTED;
2148         }
2149         if (0 != __stt_check_privilege()) {
2150                 return STT_ERROR_PERMISSION_DENIED;
2151         }
2152         if (0 != __stt_check_handle(stt, &client)) {
2153                 return STT_ERROR_INVALID_PARAMETER;
2154         }
2155
2156         if (NULL == callback)
2157                 return STT_ERROR_INVALID_PARAMETER;
2158
2159         if (STT_STATE_CREATED != client->current_state) {
2160                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2161                 return STT_ERROR_INVALID_STATE;
2162         }
2163
2164         client->engine_changed_cb = callback;
2165         client->engine_changed_user_data = user_data;
2166
2167         return 0;
2168 }
2169
2170 int stt_unset_engine_changed_cb(stt_h stt)
2171 {
2172         stt_client_s* client = NULL;
2173         if (0 != __stt_get_feature_enabled()) {
2174                 return STT_ERROR_NOT_SUPPORTED;
2175         }
2176         if (0 != __stt_check_privilege()) {
2177                 return STT_ERROR_PERMISSION_DENIED;
2178         }
2179         if (0 != __stt_check_handle(stt, &client)) {
2180                 return STT_ERROR_INVALID_PARAMETER;
2181         }
2182
2183         if (STT_STATE_CREATED != client->current_state) {
2184                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2185                 return STT_ERROR_INVALID_STATE;
2186         }
2187
2188         client->engine_changed_cb = NULL;
2189         client->engine_changed_user_data = NULL;
2190
2191         return 0;
2192 }