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