Add get/set private data function
[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_INVALID_STATE;
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 0
1470         ret = -1;
1471         /* do request */
1472         int count = 0;
1473         while (0 != ret) {
1474                 ret = stt_dbus_request_start(client->uid, temp, type, client->silence, appid);
1475                 if (0 > ret) {
1476                         /* Failure */
1477                         if (STT_ERROR_TIMED_OUT != ret) {
1478                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to start : %s", __stt_get_error_code(ret));
1479                                 if (NULL != temp)       free(temp);
1480                                 return ret;
1481                         } else {
1482                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry to start");
1483                                 usleep(10000);
1484                                 count++;
1485                                 if (STT_RETRY_COUNT == count) {
1486                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1487                                         if (NULL != temp)       free(temp);
1488                                         return ret;
1489                                 }
1490                         }
1491                 } else {
1492                         /* Success */
1493                         if (NULL != temp)       free(temp);
1494
1495                         if (STT_RESULT_STATE_DONE == ret) {
1496                                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Start is done : %d", ret);
1497                                 client->before_state = client->current_state;
1498                                 client->current_state = STT_STATE_RECORDING;
1499
1500                                 if (NULL != client->state_changed_cb) {
1501                                         ecore_main_loop_thread_safe_call_async(__stt_notify_state_changed, client);
1502                                 } else {
1503                                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
1504                                 }
1505                         } else if (STT_RESULT_STATE_NOT_DONE == ret) {
1506                                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Start is not done : %d", ret);
1507                                 client->internal_state = STT_INTERNAL_STATE_STARTING;
1508                         } else {
1509                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid result : %d", ret);
1510                         }
1511
1512                         ret = STT_ERROR_NONE;
1513                         break;
1514                 }
1515         }
1516 #else
1517         if (true == client->credential_needed && NULL == client->credential) {
1518                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Do not have app credential for this engine(%s)", client->current_engine_id);
1519                 return STT_ERROR_PERMISSION_DENIED;
1520         }
1521
1522         ret = stt_dbus_request_start(client->uid, temp, type, client->silence, appid, client->credential);
1523         if (0 != ret) {
1524                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to start : %s", __stt_get_error_code(ret));
1525         } else {
1526                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Start is successful but not done");
1527                 client->internal_state = STT_INTERNAL_STATE_STARTING;
1528         }
1529
1530         if (NULL != temp)       free(temp);
1531 #endif
1532         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1533         SLOG(LOG_DEBUG, TAG_STTC, " ");
1534
1535         return ret;
1536 }
1537
1538 int stt_stop(stt_h stt)
1539 {
1540         if (0 != __stt_get_feature_enabled()) {
1541                 return STT_ERROR_NOT_SUPPORTED;
1542         }
1543         if (0 != __stt_check_privilege()) {
1544                 return STT_ERROR_PERMISSION_DENIED;
1545         }
1546
1547         SLOG(LOG_DEBUG, TAG_STTC, "===== STT STOP");
1548
1549         if (NULL == stt) {
1550                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1551                 return STT_ERROR_INVALID_PARAMETER;
1552         }
1553
1554         stt_client_s* client = stt_client_get(stt);
1555         if (NULL == client) {
1556                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
1557                 return STT_ERROR_INVALID_PARAMETER;
1558         }
1559
1560         /* check state */
1561         if (client->current_state != STT_STATE_RECORDING) {
1562                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Current state(%d) is NOT RECORDING", client->current_state);
1563                 return STT_ERROR_INVALID_STATE;
1564         }
1565
1566         if (STT_INTERNAL_STATE_NONE != client->internal_state) {
1567                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is NOT none : %d", client->internal_state);
1568                 return STT_ERROR_INVALID_STATE;
1569         }
1570 #if 0
1571         int ret = -1;
1572         /* do request */
1573         int count = 0;
1574         while (0 != ret) {
1575                 ret = stt_dbus_request_stop(client->uid);
1576                 if (0 > ret) {
1577                         /* Failure */
1578                         if (STT_ERROR_TIMED_OUT != ret) {
1579                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to stop : %s", __stt_get_error_code(ret));
1580                                 return ret;
1581                         } else {
1582                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry stop");
1583                                 usleep(10000);
1584                                 count++;
1585                                 if (STT_RETRY_COUNT == count) {
1586                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1587                                         return ret;
1588                                 }
1589                         }
1590                 } else {
1591                         if (STT_RESULT_STATE_DONE == ret) {
1592                                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Stop is done : %d", ret);
1593                                 client->before_state = client->current_state;
1594                                 client->current_state = STT_STATE_PROCESSING;
1595
1596                                 if (NULL != client->state_changed_cb) {
1597                                         ecore_main_loop_thread_safe_call_async(__stt_notify_state_changed, client);
1598                                         SLOG(LOG_DEBUG, TAG_STTC, "State changed callback is called");
1599                                 } else {
1600                                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
1601                                 }
1602                         } else if (STT_RESULT_STATE_NOT_DONE == ret) {
1603                                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Stop is not done : %d", ret);
1604                                 client->internal_state = STT_INTERNAL_STATE_STOPING;
1605                         } else {
1606                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid result : %d", ret);
1607                         }
1608                         ret = STT_ERROR_NONE;
1609                         break;
1610                 }
1611         }
1612 #else
1613         int ret = stt_dbus_request_stop(client->uid);
1614
1615         if (0 != ret) {
1616                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to stop : %s", __stt_get_error_code(ret));
1617         } else {
1618                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Stop is successful but not done");
1619                 client->internal_state = STT_INTERNAL_STATE_STOPING;
1620         }
1621 #endif
1622         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1623         SLOG(LOG_DEBUG, TAG_STTC, " ");
1624
1625         return ret;
1626 }
1627
1628
1629 int stt_cancel(stt_h stt)
1630 {
1631         if (0 != __stt_get_feature_enabled()) {
1632                 return STT_ERROR_NOT_SUPPORTED;
1633         }
1634         if (0 != __stt_check_privilege()) {
1635                 return STT_ERROR_PERMISSION_DENIED;
1636         }
1637
1638         SLOG(LOG_DEBUG, TAG_STTC, "===== STT CANCEL");
1639
1640         if (NULL == stt) {
1641                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input handle is null");
1642                 return STT_ERROR_INVALID_PARAMETER;
1643         }
1644
1645         stt_client_s* client = stt_client_get(stt);
1646
1647         /* check handle */
1648         if (NULL == client) {
1649                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
1650                 return STT_ERROR_INVALID_PARAMETER;
1651         }
1652
1653         /* check state */
1654         if (STT_STATE_RECORDING != client->current_state && STT_STATE_PROCESSING != client->current_state) {
1655                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid state : Current state(%d) is 'Ready'", client->current_state);
1656                 return STT_ERROR_INVALID_STATE;
1657         }
1658
1659         if (STT_INTERNAL_STATE_NONE != client->internal_state) {
1660                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is NOT none : %d", client->internal_state);
1661                 return STT_ERROR_INVALID_STATE;
1662         }
1663 #if 0
1664         int ret = -1;
1665         /* do request */
1666         int count = 0;
1667         while (0 != ret) {
1668                 ret = stt_dbus_request_cancel(client->uid);
1669                 if (0 != ret) {
1670                         /* Failure */
1671                         if (STT_ERROR_TIMED_OUT != ret) {
1672                                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Fail to cancel : %s", __stt_get_error_code(ret));
1673                                 return ret;
1674                         } else {
1675                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1676                                 usleep(10000);
1677                                 count++;
1678                                 if (STT_RETRY_COUNT == count) {
1679                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1680                                         return ret;
1681                                 }
1682                         }
1683                 } else {
1684                         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS]");
1685
1686                         client->before_state = client->current_state;
1687                         client->current_state = STT_STATE_READY;
1688
1689                         if (NULL != client->state_changed_cb) {
1690                                 ecore_main_loop_thread_safe_call_async(__stt_notify_state_changed, client);
1691                                 SLOG(LOG_DEBUG, TAG_STTC, "State changed callback is called");
1692                         } else {
1693                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
1694                         }
1695                         ret = STT_ERROR_NONE;
1696                         break;
1697                 }
1698         }
1699 #else
1700         int ret = stt_dbus_request_cancel(client->uid);
1701         if (0 != ret) {
1702                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to cancel : %s", __stt_get_error_code(ret));
1703         } else {
1704                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Cancel is successful but not done");
1705                 client->internal_state = STT_INTERNAL_STATE_CANCELING;
1706         }
1707 #endif
1708         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1709         SLOG(LOG_DEBUG, TAG_STTC, " ");
1710
1711         return ret;
1712 }
1713
1714 int __stt_cb_set_volume(int uid, float volume)
1715 {
1716         stt_client_s* client = NULL;
1717
1718         client = stt_client_get_by_uid(uid);
1719         if (NULL == client) {
1720                 SLOG(LOG_ERROR, TAG_STTC, "Handle is NOT valid");
1721                 return STT_ERROR_INVALID_PARAMETER;
1722         }
1723
1724         if (STT_STATE_RECORDING != client->current_state) {
1725                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Invalid state : NO 'Recording' state, cur(%d)", client->current_state);
1726                 return STT_ERROR_INVALID_STATE;
1727         }
1728
1729         g_volume_db = volume;
1730         SLOG(LOG_DEBUG, TAG_STTC, "Set volume (%f)", g_volume_db);
1731
1732         return 0;
1733 }
1734
1735 int stt_get_recording_volume(stt_h stt, float* volume)
1736 {
1737         if (0 != __stt_get_feature_enabled()) {
1738                 return STT_ERROR_NOT_SUPPORTED;
1739         }
1740         if (0 != __stt_check_privilege()) {
1741                 return STT_ERROR_PERMISSION_DENIED;
1742         }
1743
1744         if (NULL == stt || NULL == volume) {
1745                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1746                 return STT_ERROR_INVALID_PARAMETER;
1747         }
1748
1749         stt_client_s* client = stt_client_get(stt);
1750
1751         /* check handle */
1752         if (NULL == client) {
1753                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
1754                 return STT_ERROR_INVALID_PARAMETER;
1755         }
1756
1757         if (STT_STATE_RECORDING != client->current_state) {
1758                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Invalid state : NO 'Recording' state, cur(%d)", client->current_state);
1759                 return STT_ERROR_INVALID_STATE;
1760         }
1761
1762         *volume = g_volume_db;
1763
1764         return STT_ERROR_NONE;
1765 }
1766
1767 bool __stt_result_time_cb(int index, int event, const char* text, long start_time, long end_time, void* user_data)
1768 {
1769         stt_client_s* client = (stt_client_s*)user_data;
1770
1771         /* check handle */
1772         if (NULL == client) {
1773                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
1774                 return EINA_FALSE;
1775         }
1776
1777         if (NULL != client->result_time_cb) {
1778                 SLOG(LOG_DEBUG, TAG_STTC, "(%d) event(%d) text(%s) start(%ld) end(%ld)",
1779                         index, event, text, start_time, end_time);
1780                 client->result_time_cb(client->stt, index, (stt_result_time_event_e)event,
1781                         text, start_time, end_time, client->result_time_user_data);
1782         } else {
1783                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Callback is NULL");
1784                 return false;
1785         }
1786
1787         return true;
1788 }
1789
1790 int stt_foreach_detailed_result(stt_h stt, stt_result_time_cb callback, void* user_data)
1791 {
1792         if (0 != __stt_get_feature_enabled()) {
1793                 return STT_ERROR_NOT_SUPPORTED;
1794         }
1795         if (0 != __stt_check_privilege()) {
1796                 return STT_ERROR_PERMISSION_DENIED;
1797         }
1798
1799         SLOG(LOG_DEBUG, TAG_STTC, "===== STT FOREACH DETAILED RESULT");
1800
1801         if (NULL == callback) {
1802                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1803                 return STT_ERROR_INVALID_PARAMETER;
1804         }
1805
1806         stt_client_s* client = stt_client_get(stt);
1807
1808         /* check handle */
1809         if (NULL == client) {
1810                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail : A handle is not valid");
1811                 return STT_ERROR_INVALID_PARAMETER;
1812         }
1813
1814         client->result_time_cb = callback;
1815         client->result_time_user_data = user_data;
1816
1817         int ret = -1;
1818         ret = stt_config_mgr_foreach_time_info(__stt_result_time_cb, client);
1819         ret = __stt_convert_config_error_code(ret);
1820         if (0 != ret) {
1821                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to foreach time info : %s", __stt_get_error_code(ret));
1822         }
1823
1824         client->result_time_cb = NULL;
1825         client->result_time_user_data = NULL;
1826
1827         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1828         SLOG(LOG_DEBUG, TAG_STTC, " ");
1829
1830         return ret;
1831 }
1832
1833 static Eina_Bool __stt_notify_error(void *data)
1834 {
1835         stt_client_s* client = (stt_client_s*)data;
1836
1837         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error from sttd");
1838
1839         /* check handle */
1840         if (NULL == client) {
1841                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
1842                 return EINA_FALSE;
1843         }
1844
1845         if (NULL == stt_client_get_by_uid(client->uid))
1846                 return EINA_FALSE;
1847
1848         if (NULL != client->error_cb) {
1849                 stt_client_use_callback(client);
1850                 g_err_callback_status = true;
1851                 client->error_cb(client->stt, client->reason, client->error_user_data);
1852                 g_err_callback_status = false;
1853                 stt_client_not_use_callback(client);
1854                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is called : reason [%d]", client->reason);
1855         } else {
1856                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null");
1857         }
1858
1859         return EINA_FALSE;
1860 }
1861
1862 int __stt_cb_error(int uid, int reason, char* err_msg)
1863 {
1864         stt_client_s* client = stt_client_get_by_uid(uid);
1865         if (NULL == client) {
1866                 SLOG(LOG_ERROR, TAG_STTC, "Handle not found");
1867                 return -1;
1868         }
1869
1870         client->reason = reason;
1871         client->internal_state = STT_INTERNAL_STATE_NONE;
1872         if (NULL != client->err_msg) {
1873                 free(client->err_msg);
1874                 client->err_msg = NULL;
1875         }
1876         client->err_msg = strdup(err_msg);
1877
1878         SLOG(LOG_INFO, TAG_STTC, "internal state is initialized to 0");
1879
1880         if (NULL != client->error_cb) {
1881                 ecore_timer_add(0, __stt_notify_error, client);
1882         } else {
1883                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null");
1884         }
1885
1886         return 0;
1887 }
1888
1889 static void __stt_notify_state_changed(void *data)
1890 {
1891         stt_client_s* client = (stt_client_s*)data;
1892
1893         /* check handle */
1894         if (NULL == client) {
1895                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
1896                 return;
1897         }
1898
1899         if (NULL == stt_client_get_by_uid(client->uid)) {
1900                 return;
1901         }
1902
1903         if (STT_INTERNAL_STATE_STARTING == client->internal_state && STT_STATE_RECORDING == client->current_state) {
1904                 client->internal_state = STT_INTERNAL_STATE_NONE;
1905                 SLOG(LOG_DEBUG, TAG_STTC, "Internal state change to NONE");
1906         } else if (STT_INTERNAL_STATE_STOPING == client->internal_state && STT_STATE_PROCESSING == client->current_state) {
1907                 client->internal_state = STT_INTERNAL_STATE_NONE;
1908                 SLOG(LOG_DEBUG, TAG_STTC, "Internal state change to NONE");
1909         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state && STT_STATE_READY == client->current_state) {
1910                 client->internal_state = STT_INTERNAL_STATE_NONE;
1911                 SLOG(LOG_DEBUG, TAG_STTC, "Internal state change to NONE");
1912         }
1913
1914         if (NULL != client->state_changed_cb) {
1915                 stt_client_use_callback(client);
1916                 client->state_changed_cb(client->stt, client->before_state,
1917                         client->current_state, client->state_changed_user_data);
1918                 stt_client_not_use_callback(client);
1919                 SLOG(LOG_DEBUG, TAG_STTC, "State changed callback is called");
1920         } else {
1921                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
1922         }
1923
1924         return;
1925 }
1926
1927 static Eina_Bool __stt_notify_result(void *data)
1928 {
1929         stt_client_s* client = (stt_client_s*)data;
1930
1931         /* check handle */
1932         if (NULL == client) {
1933                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
1934                 return EINA_FALSE;
1935         }
1936
1937         if (NULL == stt_client_get_by_uid(client->uid)) {
1938                 return EINA_FALSE;
1939         }
1940
1941         if (NULL != client->recognition_result_cb) {
1942                 stt_client_use_callback(client);
1943                 client->recognition_result_cb(client->stt, client->event, (const char**)client->data_list, client->data_count,
1944                         client->msg, client->recognition_result_user_data);
1945                 stt_client_not_use_callback(client);
1946                 SLOG(LOG_DEBUG, TAG_STTC, "client recognition result callback called");
1947         } else {
1948                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] User recognition result callback is NULL");
1949         }
1950
1951         if (NULL != client->msg) {
1952                 free(client->msg);
1953                 client->msg = NULL;
1954         }
1955
1956         if (NULL != client->data_list) {
1957                 char **temp = NULL;
1958                 temp = client->data_list;
1959
1960                 int i = 0;
1961                 for (i = 0; i < client->data_count; i++) {
1962                         if (NULL != temp[i]) {
1963                                 free(temp[i]);
1964                                 temp[i] = NULL;
1965                         } else {
1966                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Result data is error");
1967                         }
1968                 }
1969                 free(client->data_list);
1970                 client->data_list = NULL;
1971         }
1972
1973         client->data_count = 0;
1974
1975         stt_config_mgr_remove_time_info_file();
1976
1977         if (STT_RESULT_EVENT_FINAL_RESULT == client->event || STT_RESULT_EVENT_ERROR == client->event) {
1978                 client->before_state = client->current_state;
1979                 client->current_state = STT_STATE_READY;
1980
1981                 if (NULL != client->state_changed_cb) {
1982                         ecore_main_loop_thread_safe_call_async(__stt_notify_state_changed, client);
1983                 } else {
1984                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
1985                 }
1986         }
1987
1988         return EINA_FALSE;
1989 }
1990
1991 int __stt_cb_result(int uid, int event, char** data, int data_count, const char* msg)
1992 {
1993         stt_client_s* client = NULL;
1994
1995         client = stt_client_get_by_uid(uid);
1996         if (NULL == client) {
1997                 SLOG(LOG_ERROR, TAG_STTC, "Handle is NOT valid");
1998                 return STT_ERROR_INVALID_PARAMETER;
1999         }
2000
2001         if (NULL != msg)
2002                 SLOG(LOG_DEBUG, TAG_STTC, "Recognition Result Message = %s", msg);
2003
2004         int i = 0;
2005         for (i = 0; i < data_count; i++) {
2006                 if (NULL != data[i])
2007                         SLOG(LOG_DEBUG, TAG_STTC, "Recognition Result[%d] = %s", i, data[i]);
2008         }
2009
2010         if (NULL != client->recognition_result_cb) {
2011                 client->event = event;
2012                 if (NULL != msg) {
2013                         client->msg = strdup(msg);
2014                 }
2015
2016                 client->data_count = data_count;
2017
2018                 if (data_count > 0) {
2019                         char **temp = NULL;
2020                         temp = (char**)calloc(data_count, sizeof(char*));
2021                         if (NULL == temp) {
2022                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory");
2023                                 return STT_ERROR_OUT_OF_MEMORY;
2024                         }
2025
2026                         for (i = 0; i < data_count; i++) {
2027                                 if (NULL != data[i])
2028                                         temp[i] = strdup(data[i]);
2029                                 else
2030                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Result data is error");
2031                         }
2032
2033                         client->data_list = temp;
2034                 }
2035         } else {
2036                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] User result callback is null");
2037         }
2038
2039         ecore_timer_add(0, __stt_notify_result, client);
2040
2041         return STT_ERROR_NONE;
2042 }
2043
2044 int __stt_cb_set_state(int uid, int state)
2045 {
2046         stt_client_s* client = stt_client_get_by_uid(uid);
2047         if (NULL == client) {
2048                 SLOG(LOG_ERROR, TAG_STTC, "Handle not found");
2049                 return -1;
2050         }
2051
2052         stt_state_e state_from_daemon = (stt_state_e)state;
2053
2054         if (client->current_state == state_from_daemon) {
2055                 SLOG(LOG_DEBUG, TAG_STTC, "Current state has already been %d", client->current_state);
2056                 return 0;
2057         }
2058
2059         client->before_state = client->current_state;
2060         client->current_state = state_from_daemon;
2061
2062         ecore_main_loop_thread_safe_call_async(__stt_notify_state_changed, client);
2063         return 0;
2064 }
2065
2066 int stt_set_recognition_result_cb(stt_h stt, stt_recognition_result_cb callback, void* user_data)
2067 {
2068         if (0 != __stt_get_feature_enabled()) {
2069                 return STT_ERROR_NOT_SUPPORTED;
2070         }
2071         if (0 != __stt_check_privilege()) {
2072                 return STT_ERROR_PERMISSION_DENIED;
2073         }
2074
2075         if (stt == NULL || callback == NULL)
2076                 return STT_ERROR_INVALID_PARAMETER;
2077
2078         stt_client_s* client = stt_client_get(stt);
2079
2080         /* check handle */
2081         if (NULL == client) {
2082                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
2083                 return STT_ERROR_INVALID_PARAMETER;
2084         }
2085
2086         if (STT_STATE_CREATED != client->current_state) {
2087                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2088                 return STT_ERROR_INVALID_STATE;
2089         }
2090
2091         client->recognition_result_cb = callback;
2092         client->recognition_result_user_data = user_data;
2093
2094         return 0;
2095 }
2096
2097 int stt_unset_recognition_result_cb(stt_h stt)
2098 {
2099         if (0 != __stt_get_feature_enabled()) {
2100                 return STT_ERROR_NOT_SUPPORTED;
2101         }
2102         if (0 != __stt_check_privilege()) {
2103                 return STT_ERROR_PERMISSION_DENIED;
2104         }
2105
2106         if (NULL == stt)
2107                 return STT_ERROR_INVALID_PARAMETER;
2108
2109         stt_client_s* client = stt_client_get(stt);
2110
2111         /* check handle */
2112         if (NULL == client) {
2113                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
2114                 return STT_ERROR_INVALID_PARAMETER;
2115         }
2116
2117         if (STT_STATE_CREATED != client->current_state) {
2118                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2119                 return STT_ERROR_INVALID_STATE;
2120         }
2121
2122         client->recognition_result_cb = NULL;
2123         client->recognition_result_user_data = NULL;
2124
2125         return 0;
2126 }
2127
2128 int stt_set_state_changed_cb(stt_h stt, stt_state_changed_cb callback, void* user_data)
2129 {
2130         if (0 != __stt_get_feature_enabled()) {
2131                 return STT_ERROR_NOT_SUPPORTED;
2132         }
2133         if (0 != __stt_check_privilege()) {
2134                 return STT_ERROR_PERMISSION_DENIED;
2135         }
2136
2137         if (NULL == stt || NULL == callback)
2138                 return STT_ERROR_INVALID_PARAMETER;
2139
2140         stt_client_s* client = stt_client_get(stt);
2141
2142         /* check handle */
2143         if (NULL == client) {
2144                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
2145                 return STT_ERROR_INVALID_PARAMETER;
2146         }
2147
2148         if (STT_STATE_CREATED != client->current_state) {
2149                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2150                 return STT_ERROR_INVALID_STATE;
2151         }
2152
2153         client->state_changed_cb = callback;
2154         client->state_changed_user_data = user_data;
2155
2156         return 0;
2157 }
2158
2159 int stt_unset_state_changed_cb(stt_h stt)
2160 {
2161         if (0 != __stt_get_feature_enabled()) {
2162                 return STT_ERROR_NOT_SUPPORTED;
2163         }
2164         if (0 != __stt_check_privilege()) {
2165                 return STT_ERROR_PERMISSION_DENIED;
2166         }
2167
2168         if (NULL == stt)
2169                 return STT_ERROR_INVALID_PARAMETER;
2170
2171         stt_client_s* client = stt_client_get(stt);
2172
2173         /* check handle */
2174         if (NULL == client) {
2175                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
2176                 return STT_ERROR_INVALID_PARAMETER;
2177         }
2178
2179         if (STT_STATE_CREATED != client->current_state) {
2180                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2181                 return STT_ERROR_INVALID_STATE;
2182         }
2183
2184         client->state_changed_cb = NULL;
2185         client->state_changed_user_data = NULL;
2186
2187         return 0;
2188 }
2189
2190 int stt_set_error_cb(stt_h stt, stt_error_cb callback, void* user_data)
2191 {
2192         if (0 != __stt_get_feature_enabled()) {
2193                 return STT_ERROR_NOT_SUPPORTED;
2194         }
2195         if (0 != __stt_check_privilege()) {
2196                 return STT_ERROR_PERMISSION_DENIED;
2197         }
2198
2199         if (NULL == stt || NULL == callback)
2200                 return STT_ERROR_INVALID_PARAMETER;
2201
2202         stt_client_s* client = stt_client_get(stt);
2203
2204         /* check handle */
2205         if (NULL == client) {
2206                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
2207                 return STT_ERROR_INVALID_PARAMETER;
2208         }
2209
2210         if (STT_STATE_CREATED != client->current_state) {
2211                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2212                 return STT_ERROR_INVALID_STATE;
2213         }
2214
2215         client->error_cb = callback;
2216         client->error_user_data = user_data;
2217
2218         return 0;
2219 }
2220
2221 int stt_unset_error_cb(stt_h stt)
2222 {
2223         if (0 != __stt_get_feature_enabled()) {
2224                 return STT_ERROR_NOT_SUPPORTED;
2225         }
2226         if (0 != __stt_check_privilege()) {
2227                 return STT_ERROR_PERMISSION_DENIED;
2228         }
2229
2230         if (NULL == stt)
2231                 return STT_ERROR_INVALID_PARAMETER;
2232
2233         stt_client_s* client = stt_client_get(stt);
2234
2235         /* check handle */
2236         if (NULL == client) {
2237                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
2238                 return STT_ERROR_INVALID_PARAMETER;
2239         }
2240
2241         if (STT_STATE_CREATED != client->current_state) {
2242                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2243                 return STT_ERROR_INVALID_STATE;
2244         }
2245
2246         client->error_cb = NULL;
2247         client->error_user_data = NULL;
2248
2249         return 0;
2250 }
2251
2252 int stt_set_default_language_changed_cb(stt_h stt, stt_default_language_changed_cb callback, void* user_data)
2253 {
2254         if (0 != __stt_get_feature_enabled()) {
2255                 return STT_ERROR_NOT_SUPPORTED;
2256         }
2257         if (0 != __stt_check_privilege()) {
2258                 return STT_ERROR_PERMISSION_DENIED;
2259         }
2260
2261         if (NULL == stt || NULL == callback)
2262                 return STT_ERROR_INVALID_PARAMETER;
2263
2264         stt_client_s* client = stt_client_get(stt);
2265
2266         /* check handle */
2267         if (NULL == client) {
2268                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
2269                 return STT_ERROR_INVALID_PARAMETER;
2270         }
2271
2272         if (STT_STATE_CREATED != client->current_state) {
2273                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2274                 return STT_ERROR_INVALID_STATE;
2275         }
2276
2277         client->default_lang_changed_cb = callback;
2278         client->default_lang_changed_user_data = user_data;
2279
2280         return 0;
2281 }
2282
2283 int stt_unset_default_language_changed_cb(stt_h stt)
2284 {
2285         if (0 != __stt_get_feature_enabled()) {
2286                 return STT_ERROR_NOT_SUPPORTED;
2287         }
2288         if (0 != __stt_check_privilege()) {
2289                 return STT_ERROR_PERMISSION_DENIED;
2290         }
2291
2292         if (NULL == stt)
2293                 return STT_ERROR_INVALID_PARAMETER;
2294
2295         stt_client_s* client = stt_client_get(stt);
2296
2297         /* check handle */
2298         if (NULL == client) {
2299                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
2300                 return STT_ERROR_INVALID_PARAMETER;
2301         }
2302
2303         if (STT_STATE_CREATED != client->current_state) {
2304                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2305                 return STT_ERROR_INVALID_STATE;
2306         }
2307
2308         client->default_lang_changed_cb = NULL;
2309         client->default_lang_changed_user_data = NULL;
2310
2311         return 0;
2312 }
2313
2314 int stt_set_engine_changed_cb(stt_h stt, stt_engine_changed_cb callback, void* user_data)
2315 {
2316         if (0 != __stt_get_feature_enabled()) {
2317                 return STT_ERROR_NOT_SUPPORTED;
2318         }
2319         if (0 != __stt_check_privilege()) {
2320                 return STT_ERROR_PERMISSION_DENIED;
2321         }
2322
2323         if (NULL == stt || NULL == callback)
2324                 return STT_ERROR_INVALID_PARAMETER;
2325
2326         stt_client_s* client = stt_client_get(stt);
2327
2328         /* check handle */
2329         if (NULL == client) {
2330                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
2331                 return STT_ERROR_INVALID_PARAMETER;
2332         }
2333
2334         if (STT_STATE_CREATED != client->current_state) {
2335                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2336                 return STT_ERROR_INVALID_STATE;
2337         }
2338
2339         client->engine_changed_cb = callback;
2340         client->engine_changed_user_data = user_data;
2341
2342         return 0;
2343 }
2344
2345 int stt_unset_engine_changed_cb(stt_h stt)
2346 {
2347         if (0 != __stt_get_feature_enabled()) {
2348                 return STT_ERROR_NOT_SUPPORTED;
2349         }
2350         if (0 != __stt_check_privilege()) {
2351                 return STT_ERROR_PERMISSION_DENIED;
2352         }
2353
2354         if (NULL == stt)
2355                 return STT_ERROR_INVALID_PARAMETER;
2356
2357         stt_client_s* client = stt_client_get(stt);
2358
2359         /* check handle */
2360         if (NULL == client) {
2361                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
2362                 return STT_ERROR_INVALID_PARAMETER;
2363         }
2364
2365         if (STT_STATE_CREATED != client->current_state) {
2366                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2367                 return STT_ERROR_INVALID_STATE;
2368         }
2369
2370         client->engine_changed_cb = NULL;
2371         client->engine_changed_user_data = NULL;
2372
2373         return 0;
2374 }