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