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