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