Fix the data type for uid
[platform/core/uifw/stt.git] / client / stt.c
1 /*
2 *  Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14 #include <aul.h>
15 #include <cynara-client.h>
16 #include <cynara-error.h>
17 #include <cynara-session.h>
18 #include <dirent.h>
19 #include <Ecore.h>
20 #include <fcntl.h>
21 #include <pthread.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <sys/wait.h>
25 #include <system_info.h>
26 #include <unistd.h>
27 #include <buxton2.h>
28 #include <sound_manager.h>
29 #include <sound_manager_internal.h>
30
31 #include "stt.h"
32 #include "stt_client.h"
33 #include "stt_dbus.h"
34 #include "stt_config_mgr.h"
35 #include "stt_internal.h"
36 #include "stt_main.h"
37
38
39 static void __stt_notify_state_changed(void *data);
40 static void __stt_notify_error(void *data);
41
42 static Ecore_Timer* g_connect_timer = NULL;
43 static float g_volume_db = 0;
44
45 static int g_feature_enabled = -1;
46
47 static pthread_mutex_t g_cynara_mutex = PTHREAD_MUTEX_INITIALIZER;
48
49 static cynara *p_cynara = NULL;
50
51 static bool g_err_callback_status = false;
52
53 /* for changing volume on each sound stream */
54 static sound_stream_ducking_h g_media_stream_ducking;
55 static sound_stream_ducking_h g_system_stream_ducking;
56 static sound_stream_ducking_h g_notification_stream_ducking;
57 static sound_stream_ducking_h g_alarm_stream_ducking;
58
59 #define STT_BG_VOLUME_RATIO_FARFIELD    0.0
60 #define STT_BG_VOLUME_RATIO_NEARFIELD   0.7
61 #define SND_MGR_DUCKING_DURATION 500
62
63 const char* stt_tag()
64 {
65         //LCOV_EXCL_START
66         return "sttc";
67         //LCOV_EXCL_STOP
68 }
69
70 static int __stt_get_feature_enabled()
71 {
72         if (0 == g_feature_enabled) {
73                 //LCOV_EXCL_START
74                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] STT NOT supported");
75                 return STT_ERROR_NOT_SUPPORTED;
76                 //LCOV_EXCL_STOP
77         } else if (-1 == g_feature_enabled) {
78                 bool stt_supported = false;
79                 bool mic_supported = false;
80                 if (0 == system_info_get_platform_bool(STT_FEATURE_PATH, &stt_supported)) {
81                         if (0 == system_info_get_platform_bool(STT_MIC_FEATURE_PATH, &mic_supported)) {
82                                 if (false == stt_supported || false == mic_supported) {
83                                         //LCOV_EXCL_START
84                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] STT NOT supported");
85                                         g_feature_enabled = 0;
86                                         return STT_ERROR_NOT_SUPPORTED;
87                                         //LCOV_EXCL_STOP
88                                 }
89
90                                 g_feature_enabled = 1;
91                         } else {
92                                 //LCOV_EXCL_START
93                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get feature value");
94                                 return STT_ERROR_NOT_SUPPORTED;
95                                 //LCOV_EXCL_STOP
96                         }
97                 } else {
98                         //LCOV_EXCL_START
99                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get feature value");
100                         return STT_ERROR_NOT_SUPPORTED;
101                         //LCOV_EXCL_STOP
102                 }
103         }
104
105         return 0;
106 }
107
108 static int __check_privilege_initialize()
109 {
110         int ret = cynara_initialize(&p_cynara, NULL);
111         if (CYNARA_API_SUCCESS != ret)
112                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] fail to initialize"); //LCOV_EXCL_LINE
113
114         return ret == CYNARA_API_SUCCESS;
115 }
116
117 static bool __check_privilege(const char* uid, const char * privilege)
118 {
119         FILE *fp = NULL;
120         char label_path[1024] = "/proc/self/attr/current";
121         char smack_label[1024] = {'\0',};
122
123         if (!p_cynara) {
124                 return false;
125         }
126
127         fp = fopen(label_path, "r");
128         if (fp != NULL) {
129                 if (0 >= fread(smack_label, 1, sizeof(smack_label), fp))
130                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] fail to fread"); //LCOV_EXCL_LINE
131
132                 fclose(fp);
133         }
134
135         pid_t pid = getpid();
136         char *session = cynara_session_from_pid(pid);
137         int ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
138         if (session) {
139                 free(session);
140                 session = NULL;
141         }
142
143         if (ret != CYNARA_API_ACCESS_ALLOWED) {
144                 SLOG(LOG_DEBUG, TAG_STTC, "[Client]cynara_check returned %d(Denied)", ret);
145                 return false;
146         }
147         return true;
148 }
149
150 static void __check_privilege_deinitialize()
151 {
152         if (p_cynara)
153                 cynara_finish(p_cynara);
154         p_cynara = NULL;
155 }
156
157 static int __stt_check_privilege()
158 {
159         pthread_mutex_lock(&g_cynara_mutex);
160
161         bool ret = true;
162         ret = __check_privilege_initialize();
163         if (false == ret) {
164                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] privilege initialize is failed"); //LCOV_EXCL_LINE
165                 pthread_mutex_unlock(&g_cynara_mutex);
166                 return STT_ERROR_PERMISSION_DENIED;
167         }
168
169         char uid[16];
170         snprintf(uid, 16, "%d", getuid());
171         ret = true;
172         ret = __check_privilege(uid, STT_PRIVILEGE_RECORDER);
173         __check_privilege_deinitialize();
174         if (false == ret) {
175                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Permission is denied"); //LCOV_EXCL_LINE
176                 pthread_mutex_unlock(&g_cynara_mutex);
177                 return STT_ERROR_PERMISSION_DENIED;
178         }
179
180         pthread_mutex_unlock(&g_cynara_mutex);
181         return STT_ERROR_NONE;
182 }
183
184 static int __stt_check_privilege_for_applaunch()
185 {
186         pthread_mutex_lock(&g_cynara_mutex);
187
188         bool ret = true;
189         ret = __check_privilege_initialize();
190         if (false == ret) {
191                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] privilege initialize is failed (applaunch)"); //LCOV_EXCL_LINE
192                 pthread_mutex_unlock(&g_cynara_mutex);
193                 return STT_ERROR_PERMISSION_DENIED;
194         }
195
196         char uid[16];
197         snprintf(uid, 16, "%d", getuid());
198         ret = true;
199         ret = __check_privilege(uid, STT_PRIVILEGE_APPLAUNCH);
200         __check_privilege_deinitialize();
201         if (false == ret) {
202                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Permission is denied : appmanager.launch"); //LCOV_EXCL_LINE
203                 pthread_mutex_unlock(&g_cynara_mutex);
204                 return STT_ERROR_PERMISSION_DENIED;
205         }
206
207         pthread_mutex_unlock(&g_cynara_mutex);
208         return STT_ERROR_NONE;
209 }
210
211 static const char* __stt_get_error_code(stt_error_e err)
212 {
213         //LCOV_EXCL_START
214         switch (err) {
215         case STT_ERROR_NONE:                    return "STT_ERROR_NONE";
216         case STT_ERROR_OUT_OF_MEMORY:           return "STT_ERROR_OUT_OF_MEMORY";
217         case STT_ERROR_IO_ERROR:                return "STT_ERROR_IO_ERROR";
218         case STT_ERROR_INVALID_PARAMETER:       return "STT_ERROR_INVALID_PARAMETER";
219         case STT_ERROR_TIMED_OUT:               return "STT_ERROR_TIMED_OUT";
220         case STT_ERROR_RECORDER_BUSY:           return "STT_ERROR_RECORDER_BUSY";
221         case STT_ERROR_OUT_OF_NETWORK:          return "STT_ERROR_OUT_OF_NETWORK";
222         case STT_ERROR_PERMISSION_DENIED:       return "STT_ERROR_PERMISSION_DENIED";
223         case STT_ERROR_NOT_SUPPORTED:           return "STT_ERROR_NOT_SUPPORTED";
224         case STT_ERROR_INVALID_STATE:           return "STT_ERROR_INVALID_STATE";
225         case STT_ERROR_INVALID_LANGUAGE:        return "STT_ERROR_INVALID_LANGUAGE";
226         case STT_ERROR_ENGINE_NOT_FOUND:        return "STT_ERROR_ENGINE_NOT_FOUND";
227         case STT_ERROR_OPERATION_FAILED:        return "STT_ERROR_OPERATION_FAILED";
228         case STT_ERROR_NOT_SUPPORTED_FEATURE:   return "STT_ERROR_NOT_SUPPORTED_FEATURE";
229         case STT_ERROR_SERVICE_RESET:           return "STT_ERROR_SERVICE_RESET";
230         default:
231                 return "Invalid error code";
232         }
233         //LCOV_EXCL_STOP
234 }
235
236 static int __stt_convert_config_error_code(stt_config_error_e code)
237 {
238         //LCOV_EXCL_START
239         if (code == STT_CONFIG_ERROR_NONE)                      return STT_ERROR_NONE;
240         if (code == STT_CONFIG_ERROR_OUT_OF_MEMORY)             return STT_ERROR_OUT_OF_MEMORY;
241         if (code == STT_CONFIG_ERROR_IO_ERROR)                  return STT_ERROR_IO_ERROR;
242         if (code == STT_CONFIG_ERROR_INVALID_PARAMETER)         return STT_ERROR_INVALID_PARAMETER;
243         if (code == STT_CONFIG_ERROR_PERMISSION_DENIED)         return STT_ERROR_PERMISSION_DENIED;
244         if (code == STT_CONFIG_ERROR_NOT_SUPPORTED)             return STT_ERROR_NOT_SUPPORTED;
245         if (code == STT_CONFIG_ERROR_INVALID_STATE)             return STT_ERROR_INVALID_STATE;
246         if (code == STT_CONFIG_ERROR_INVALID_LANGUAGE)          return STT_ERROR_INVALID_LANGUAGE;
247         if (code == STT_CONFIG_ERROR_ENGINE_NOT_FOUND)          return STT_ERROR_ENGINE_NOT_FOUND;
248         if (code == STT_CONFIG_ERROR_OPERATION_FAILED)          return STT_ERROR_OPERATION_FAILED;
249
250         return code;
251         //LCOV_EXCL_STOP
252 }
253
254 void __stt_config_lang_changed_cb(const char* before_language, const char* current_language, void* user_data)
255 {
256         SLOG(LOG_DEBUG, TAG_STTC, "Language changed : Before lang(%s) Current lang(%s)",
257                 before_language, current_language);
258
259         if (0 == strcmp(before_language, current_language)) {
260                 return;
261         }
262
263         GList* client_list = NULL;
264         client_list = stt_client_get_client_list();
265
266         GList *iter = NULL;
267         stt_client_s *data = NULL;
268
269         if (g_list_length(client_list) > 0) {
270                 /* Get a first item */
271                 iter = g_list_first(client_list);
272
273                 while (NULL != iter) {
274                         data = iter->data;
275                         if (NULL != data->default_lang_changed_cb) {
276                                 SLOG(LOG_DEBUG, TAG_STTC, "Call default language changed callback : uid(%u)", data->uid);
277                                 data->default_lang_changed_cb(data->stt, before_language, current_language,
278                                         data->default_lang_changed_user_data);
279                         }
280
281                         /* Next item */
282                         iter = g_list_next(iter);
283                 }
284         }
285
286         return;
287 }
288
289 static Eina_Bool __reconnect_by_engine_changed(void *data)
290 {
291         stt_h stt = (stt_h)data;
292
293         stt_client_s* client = stt_client_get(stt);
294         if (NULL == client) {
295                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] A handle is not valid");
296                 return EINA_FALSE;
297         }
298
299         if (STT_STATE_READY != client->current_state) {
300                 usleep(10000);
301                 return EINA_TRUE;
302         }
303
304         int ret = stt_unprepare(stt);
305         if (0 != ret) {
306                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret);
307         }
308         ret = stt_prepare(stt);
309         if (0 != ret) {
310                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret);
311         }
312
313         return EINA_FALSE;
314 }
315
316 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)
317 {
318         stt_h stt = (stt_h)user_data;
319
320         stt_client_s* client = stt_client_get(stt);
321         if (NULL == client) {
322                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] A handle is not valid");
323                 return;
324         }
325
326         if (NULL != engine_id)  SLOG(LOG_DEBUG, TAG_STTC, "Engine id(%s)", engine_id);
327         if (NULL != setting)    SLOG(LOG_DEBUG, TAG_STTC, "Engine setting(%s)", setting);
328         if (NULL != language)   SLOG(LOG_DEBUG, TAG_STTC, "Language(%s)", language);
329         SLOG(LOG_DEBUG, TAG_STTC, "Silence(%s), Credential(%s)", support_silence ? "on" : "off", need_credential ? "need" : "no need");
330
331         /* When the default engine is changed, please unload the old engine and load the new one. */
332         int ret = -1;
333
334         if (NULL == client->current_engine_id) {
335                 if (STT_STATE_RECORDING == client->current_state || STT_STATE_PROCESSING == client->current_state) {
336                         SLOG(LOG_INFO, TAG_STTC, "[INFO] stt cancel is invoked by engine_changed_cb, state(%d)", client->current_state);
337                         ret = stt_cancel(stt);
338                         if (0 != ret) {
339                                 SLOG(LOG_DEBUG, TAG_STTC, "[DEBUG] STT client cancelling...");
340                         }
341
342                         ecore_idler_add(__reconnect_by_engine_changed, (void*)stt);
343                 } else if (STT_STATE_READY == client->current_state) {
344                         ret = stt_unprepare(stt);
345                         if (0 != ret) {
346                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret);
347                         }
348                         ret = stt_prepare(stt);
349                         if (0 != ret) {
350                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret);
351                         }
352                 }
353         }
354
355         /* call callback function */
356         if (NULL != client->engine_changed_cb) {
357                 client->engine_changed_cb(stt, engine_id, language, support_silence, need_credential, client->engine_changed_user_data);
358         } else {
359                 SLOG(LOG_WARN, TAG_STTC, "No registered callback function for engine change");
360         }
361         return;
362 }
363
364 static int __stt_check_handle(stt_h stt, stt_client_s** client)
365 {
366         if (NULL == stt) {
367                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input handle is null");
368                 return STT_ERROR_INVALID_PARAMETER;
369         }
370
371         stt_client_s* temp = NULL;
372         temp = stt_client_get(stt);
373
374         /* check handle */
375         if (NULL == temp) {
376                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
377                 return STT_ERROR_INVALID_PARAMETER;
378         }
379         *client = temp;
380
381         return STT_ERROR_NONE;
382 }
383
384 int stt_create(stt_h* stt)
385 {
386         if (0 != __stt_get_feature_enabled()) {
387                 return STT_ERROR_NOT_SUPPORTED;
388         }
389         if (0 != __stt_check_privilege()) {
390                 return STT_ERROR_PERMISSION_DENIED;
391         }
392
393         SLOG(LOG_INFO, TAG_STTC, "===== Create STT");
394
395         if (NULL == stt) {
396                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is null");
397                 return STT_ERROR_INVALID_PARAMETER;
398         }
399
400         if (0 == stt_client_get_size()) {
401                 if (0 != stt_dbus_open_connection()) {
402                         //LCOV_EXCL_START
403                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to open connection");
404                         return STT_ERROR_OPERATION_FAILED;
405                         //LCOV_EXCL_STOP
406                 }
407         }
408
409         if (0 != stt_client_new(stt)) {
410                 //LCOV_EXCL_START
411                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to create client!");
412                 return STT_ERROR_OUT_OF_MEMORY;
413                 //LCOV_EXCL_STOP
414         }
415
416         stt_client_s* client = stt_client_get(*stt);
417         if (NULL == client) {
418                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to create client"); //LCOV_EXCL_LINE
419                 stt_client_destroy(*stt);
420                 return STT_ERROR_OPERATION_FAILED;
421         }
422
423         int ret = stt_config_mgr_initialize(client->uid);
424         ret = __stt_convert_config_error_code(ret);
425         if (0 != ret) {
426                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to init config manager : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
427                 stt_client_destroy(*stt);
428                 return ret;
429         }
430
431         ret = stt_config_mgr_set_callback(client->uid, __stt_config_engine_changed_cb, __stt_config_lang_changed_cb, NULL, client->stt);
432         ret = __stt_convert_config_error_code(ret);
433         if (0 != ret) {
434                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set config changed : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
435                 stt_client_destroy(*stt);
436                 return ret;
437         }
438
439         SLOG(LOG_INFO, TAG_STTC, "[Success] uid(%u)", client->uid);
440
441         SLOG(LOG_DEBUG, TAG_STTC, "=====");
442         SLOG(LOG_DEBUG, TAG_STTC, " ");
443
444         return STT_ERROR_NONE;
445 }
446
447 int stt_destroy(stt_h stt)
448 {
449         stt_client_s* client = NULL;
450         if (0 != __stt_get_feature_enabled()) {
451                 return STT_ERROR_NOT_SUPPORTED;
452         }
453         if (0 != __stt_check_privilege()) {
454                 return STT_ERROR_PERMISSION_DENIED;
455         }
456         if (0 != __stt_check_handle(stt, &client)) {
457                 return STT_ERROR_INVALID_PARAMETER;
458         }
459
460         SLOG(LOG_INFO, TAG_STTC, "===== Destroy STT");
461
462         /* check used callback */
463         if (0 != stt_client_get_use_callback(client)) {
464                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Cannot destroy in Callback function");
465                 return STT_ERROR_OPERATION_FAILED;
466         }
467
468         stt_config_mgr_finalize(client->uid);
469
470         int ret = -1;
471
472         /* check state */
473         switch (client->current_state) {
474         case STT_STATE_PROCESSING:
475         case STT_STATE_RECORDING:
476         case STT_STATE_READY:
477                 ret = stt_dbus_request_finalize(client->uid);
478                 if (0 != ret) {
479                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request finalize : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
480                 }
481         case STT_STATE_CREATED:
482                 if (NULL != g_connect_timer) {
483                         SLOG(LOG_DEBUG, TAG_STTC, "Connect Timer is deleted");
484                         ecore_timer_del(g_connect_timer);
485                         g_connect_timer = NULL;
486                 }
487
488                 /* Free resources */
489                 stt_client_destroy(stt);
490                 break;
491         default:
492                 break;
493         }
494
495         if (0 == stt_client_get_size()) {
496                 if (0 != stt_dbus_close_connection()) {
497                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to close connection"); //LCOV_EXCL_LINE
498                 }
499         }
500
501         stt = NULL;
502
503         SLOG(LOG_INFO, TAG_STTC, "=====");
504         SLOG(LOG_DEBUG, TAG_STTC, " ");
505
506         return STT_ERROR_NONE;
507 }
508
509 static bool __stt_config_supported_engine_cb(const char* engine_id, const char* engine_name,
510                                              const char* setting, bool support_silence, void* user_data)
511 {
512         stt_h stt = (stt_h)user_data;
513
514         stt_client_s* client = stt_client_get(stt);
515         if (NULL == client) {
516                 //LCOV_EXCL_START
517                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] A handle is not valid");
518                 return false;
519                 //LCOV_EXCL_STOP
520         }
521
522         /* call callback function */
523         if (NULL != client->supported_engine_cb) {
524                 return client->supported_engine_cb(stt, engine_id, engine_name, client->supported_engine_user_data);
525         } else {
526                 SLOG(LOG_WARN, TAG_STTC, "No registered callback function of supported engine"); //LCOV_EXCL_LINE
527         }
528
529         return false;
530 }
531
532 int stt_foreach_supported_engines(stt_h stt, stt_supported_engine_cb callback, void* user_data)
533 {
534         stt_client_s* client = NULL;
535         if (0 != __stt_get_feature_enabled()) {
536                 return STT_ERROR_NOT_SUPPORTED;
537         }
538         if (0 != __stt_check_privilege()) {
539                 return STT_ERROR_PERMISSION_DENIED;
540         }
541         if (0 != __stt_check_handle(stt, &client)) {
542                 return STT_ERROR_INVALID_PARAMETER;
543         }
544
545         SLOG(LOG_INFO, TAG_STTC, "===== Foreach Supported engine");
546
547         if (NULL == callback) {
548                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
549                 return STT_ERROR_INVALID_PARAMETER;
550         }
551
552         if (client->current_state != STT_STATE_CREATED) {
553                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not CREATED", client->current_state);
554                 return STT_ERROR_INVALID_STATE;
555         }
556
557         client->supported_engine_cb = callback;
558         client->supported_engine_user_data = user_data;
559
560         int ret = 0;
561         ret = stt_config_mgr_get_engine_list(__stt_config_supported_engine_cb, client->stt);
562         ret = __stt_convert_config_error_code(ret);
563         if (0 != ret) {
564                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get engines : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
565         }
566
567         client->supported_engine_cb = NULL;
568         client->supported_engine_user_data = NULL;
569
570         SLOG(LOG_INFO, TAG_STTC, "=====");
571         SLOG(LOG_DEBUG, TAG_STTC, " ");
572
573         return ret;
574 }
575
576 int stt_get_engine(stt_h stt, char** engine_id)
577 {
578         stt_client_s* client = NULL;
579         if (0 != __stt_get_feature_enabled()) {
580                 return STT_ERROR_NOT_SUPPORTED;
581         }
582         if (0 != __stt_check_privilege()) {
583                 return STT_ERROR_PERMISSION_DENIED;
584         }
585         if (0 != __stt_check_handle(stt, &client)) {
586                 return STT_ERROR_INVALID_PARAMETER;
587         }
588
589         SLOG(LOG_INFO, TAG_STTC, "===== Get current engine");
590
591         if (NULL == engine_id) {
592                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
593                 return STT_ERROR_INVALID_PARAMETER;
594         }
595
596         if (client->current_state != STT_STATE_CREATED) {
597                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not CREATED", client->current_state);
598                 return STT_ERROR_INVALID_STATE;
599         }
600
601         int ret = 0;
602
603         if (NULL != client->current_engine_id) {
604                 *engine_id = strdup(client->current_engine_id);
605                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current engine uuid = %s", *engine_id);
606         } else {
607
608                 ret = stt_config_mgr_get_engine(engine_id);
609                 ret = __stt_convert_config_error_code(ret);
610                 if (0 != ret) {
611                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request get current engine : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
612                 } else {
613                         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current engine uuid = %s", *engine_id);
614                 }
615         }
616
617         SLOG(LOG_INFO, TAG_STTC, "=====");
618         SLOG(LOG_DEBUG, TAG_STTC, " ");
619
620         return ret;
621 }
622
623 int __stt_set_buxtonkey(const char* engine_id)
624 {
625         /* Set vconfkey */
626         struct buxton_client * bux_cli;
627         struct buxton_layer * bux_layer;
628         struct buxton_value * bux_val;
629
630         int ret = buxton_open(&bux_cli, NULL, NULL);
631         if (0 != ret) {
632                 SLOG(LOG_ERROR, stt_tag(), "[DBUS-BUXTON2] Fail to open buxton client"); //LCOV_EXCL_LINE
633                 return STT_ERROR_OPERATION_FAILED;
634         }
635         SLOG(LOG_DEBUG, stt_tag(), "[DBUS-BUXTON2] buxton_open: %d", ret);
636         bux_layer = buxton_create_layer("system");
637         if (NULL == bux_layer) {
638                 //LCOV_EXCL_START
639                 SLOG(LOG_ERROR, stt_tag(), "[DBUS-BUXTON2] buxton_create_layer FAIL");
640                 buxton_close(bux_cli);
641                 bux_cli = NULL;
642                 return STT_ERROR_OPERATION_FAILED;
643                 //LCOV_EXCL_STOP
644         }
645         bux_val = buxton_value_create_string(engine_id);
646         if (NULL == bux_val) {
647                 //LCOV_EXCL_START
648                 SLOG(LOG_ERROR, stt_tag(), "[DBUS-BUXTON2] buxton_value_create_string FAIL");
649                 buxton_free_layer(bux_layer);
650                 buxton_close(bux_cli);
651                 bux_layer = NULL;
652                 bux_cli = NULL;
653                 return STT_ERROR_OPERATION_FAILED;
654                 //LCOV_EXCL_STOP
655         }
656
657         ret = buxton_set_value_sync(bux_cli, bux_layer, STT_ENGINE_DB_CUSTOM, bux_val);
658         if (0 != ret) {
659                 //LCOV_EXCL_START
660                 SLOG(LOG_ERROR, stt_tag(), "[DBUS-BUXTON2] Fail to set value sync");
661                 buxton_value_free(bux_val);
662                 buxton_free_layer(bux_layer);
663                 buxton_close(bux_cli);
664
665                 bux_cli = NULL;
666                 bux_layer = NULL;
667                 bux_val = NULL;
668                 return STT_ERROR_OPERATION_FAILED;
669                 //LCOV_EXCL_STOP
670         }
671         SLOG(LOG_DEBUG, stt_tag(), "[DBUS-BUXTON2] buxton_set_value_sync: %d, %s", ret, STT_ENGINE_DB_CUSTOM);
672
673         buxton_value_free(bux_val);
674         buxton_free_layer(bux_layer);
675         buxton_close(bux_cli);
676
677         bux_cli = NULL;
678         bux_layer = NULL;
679         bux_val = NULL;
680
681         return STT_ERROR_NONE;
682 }
683
684 int stt_set_engine(stt_h stt, const char* engine_id)
685 {
686         stt_client_s* client = NULL;
687         if (0 != __stt_get_feature_enabled()) {
688                 return STT_ERROR_NOT_SUPPORTED;
689         }
690         if (0 != __stt_check_privilege()) {
691                 return STT_ERROR_PERMISSION_DENIED;
692         }
693         if (0 != __stt_check_privilege_for_applaunch()) {
694                 return STT_ERROR_PERMISSION_DENIED;
695         }
696         if (0 != __stt_check_handle(stt, &client)) {
697                 return STT_ERROR_INVALID_PARAMETER;
698         }
699
700         SLOG(LOG_INFO, TAG_STTC, "===== Set current engine");
701
702         if (NULL == engine_id) {
703                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
704                 return STT_ERROR_INVALID_PARAMETER;
705         }
706
707         /* check state */
708         if (client->current_state != STT_STATE_CREATED) {
709                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not CREATED", client->current_state);
710                 return STT_ERROR_INVALID_STATE;
711         }
712
713         if (NULL != client->current_engine_id) {
714                 free(client->current_engine_id);
715                 client->current_engine_id = NULL;
716         }
717
718         SLOG(LOG_INFO, TAG_STTC, "===== engined_id(%s)", engine_id);
719
720         client->current_engine_id = strdup(engine_id);
721
722         /* Set vconfkey */
723         int ret = __stt_set_buxtonkey(engine_id);
724         if (0 != ret) {
725                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] set buxtonkey Failed!!!"); //LCOV_EXCL_LINE
726                 return ret;
727         }
728
729         SLOG(LOG_INFO, TAG_STTC, "=====");
730         SLOG(LOG_DEBUG, TAG_STTC, " ");
731
732         return 0;
733 }
734
735 int stt_set_credential(stt_h stt, const char* credential)
736 {
737         stt_client_s* client = NULL;
738         if (0 != __stt_get_feature_enabled()) {
739                 return STT_ERROR_NOT_SUPPORTED;
740         }
741         if (0 != __stt_check_privilege()) {
742                 return STT_ERROR_PERMISSION_DENIED;
743         }
744         if (0 != __stt_check_handle(stt, &client)) {
745                 return STT_ERROR_INVALID_PARAMETER;
746         }
747
748         SLOG(LOG_INFO, TAG_STTC, "===== Set credential");
749
750         if (NULL == credential) {
751                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
752                 return STT_ERROR_INVALID_PARAMETER;
753         }
754
755         /* check state */
756         if (client->current_state != STT_STATE_CREATED && client->current_state != STT_STATE_READY) {
757                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not CREATED or READY", client->current_state); //LCOV_EXCL_LINE
758                 return STT_ERROR_INVALID_STATE;
759         }
760
761         if (NULL != client->credential) {
762                 free(client->credential);
763                 client->credential = NULL;
764         }
765         client->credential = strdup(credential);
766
767         SLOG(LOG_INFO, TAG_STTC, "=====");
768         SLOG(LOG_DEBUG, TAG_STTC, " ");
769
770         return STT_ERROR_NONE;
771 }
772
773 int stt_set_private_data(stt_h stt, const char* key, const char* data)
774 {
775         stt_client_s* client = NULL;
776         if (0 != __stt_get_feature_enabled()) {
777                 return STT_ERROR_NOT_SUPPORTED;
778         }
779         if (0 != __stt_check_privilege()) {
780                 return STT_ERROR_PERMISSION_DENIED;
781         }
782         if (0 != __stt_check_handle(stt, &client)) {
783                 return STT_ERROR_INVALID_PARAMETER;
784         }
785
786         SLOG(LOG_INFO, TAG_STTC, "===== Set private data");
787
788         if (NULL == key || NULL == data) {
789                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid parameter");
790                 return STT_ERROR_INVALID_PARAMETER;
791         }
792
793         /* check state */
794         if (STT_STATE_READY != client->current_state) {
795                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
796                 return STT_ERROR_INVALID_STATE;
797         }
798
799         if (true != client->internal && (0 == strcmp(key, "server") || 0 == strcmp(key, "rampcode") || 0 == strcmp(key, "epd"))) {
800                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] This is not an internal app"); //LCOV_EXCL_LINE
801                 return STT_ERROR_INVALID_PARAMETER;
802         }
803
804         int ret = -1;
805         int count = 0;
806         while (0 != ret) {
807                 ret = stt_dbus_request_set_private_data(client->uid, key, data);
808                 if (0 != ret) {
809                         //LCOV_EXCL_START
810                         if (STT_ERROR_TIMED_OUT != ret) {
811                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set private data : %s", __stt_get_error_code(ret));
812                                 return ret;
813                         } else {
814                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry : %s", __stt_get_error_code(ret));
815                                 usleep(10000);
816                                 count++;
817                                 if (STT_RETRY_COUNT == count) {
818                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
819                                         return ret;
820                                 }
821                         }
822                         //LCOV_EXCL_STOP
823                 }
824         }
825
826         SLOG(LOG_INFO, TAG_STTC, "=====");
827         SLOG(LOG_DEBUG, TAG_STTC, "");
828
829         return STT_ERROR_NONE;
830
831 }
832 int stt_get_private_data(stt_h stt, const char* key, char** data)
833 {
834         stt_client_s* client = NULL;
835         if (0 != __stt_get_feature_enabled()) {
836                 return STT_ERROR_NOT_SUPPORTED;
837         }
838         if (0 != __stt_check_privilege()) {
839                 return STT_ERROR_PERMISSION_DENIED;
840         }
841         if (0 != __stt_check_handle(stt, &client)) {
842                 return STT_ERROR_INVALID_PARAMETER;
843         }
844
845         SLOG(LOG_INFO, TAG_STTC, "===== Get private data");
846
847         if (NULL == key || NULL == data) {
848                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid parameter");
849                 return STT_ERROR_INVALID_PARAMETER;
850         }
851
852         /* check state */
853         if (STT_STATE_READY != client->current_state) {
854                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
855                 return STT_ERROR_INVALID_STATE;
856         }
857
858         int ret = -1;
859         int count = 0;
860         while (0 != ret) {
861                 ret = stt_dbus_request_get_private_data(client->uid, key, data);
862                 if (0 != ret) {
863                         //LCOV_EXCL_START
864                         if (STT_ERROR_TIMED_OUT != ret) {
865                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get private data : %s", __stt_get_error_code(ret));
866                                 return ret;
867                         } else {
868                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry : %s", __stt_get_error_code(ret));
869                                 usleep(10000);
870                                 count++;
871                                 if (STT_RETRY_COUNT == count) {
872                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
873                                         return ret;
874                                 }
875                         }
876                         //LCOV_EXCL_STOP
877                 }
878         }
879
880         if (0 == strncmp(*data, "NULL", strlen(*data))) {
881                 free(*data);
882                 *data = NULL;
883         }
884
885         SLOG(LOG_INFO, TAG_STTC, "=====");
886         SLOG(LOG_DEBUG, TAG_STTC, "");
887
888         return STT_ERROR_NONE;
889 }
890
891 //LCOV_EXCL_START
892 int stt_set_server_stt(stt_h stt, const char* key, char* user_data)
893 {
894         int ret = -1;
895         stt_client_s* client = NULL;
896
897         if (0 != __stt_get_feature_enabled()) {
898                 return STT_ERROR_NOT_SUPPORTED;
899         }
900         if (0 != __stt_check_privilege()) {
901                 return STT_ERROR_PERMISSION_DENIED;
902         }
903         if (0 != __stt_check_handle(stt, &client)) {
904                 return STT_ERROR_INVALID_PARAMETER;
905         }
906
907         SLOG(LOG_INFO, TAG_STTC, "===== Set STT server");
908
909         if (NULL == key || NULL == user_data) {
910                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid parameter");
911                 return STT_ERROR_INVALID_PARAMETER;
912         }
913
914         if (STT_STATE_CREATED != client->current_state && STT_STATE_READY != client->current_state) {
915                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] The current state is invalid (%d).", client->current_state);
916                 return STT_ERROR_INVALID_STATE;
917         }
918
919
920         client->internal = true;
921
922         char* private_key = NULL;
923         private_key = strdup(key);
924         if (NULL == private_key) {
925                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory(private_key)");
926                 return STT_ERROR_OUT_OF_MEMORY;
927         }
928
929         char* data = NULL;
930         data = strdup(user_data);
931         if (NULL == data) {
932                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory(data)");
933                 free(private_key);
934                 private_key = NULL;
935                 return STT_ERROR_OUT_OF_MEMORY;
936         }
937
938         ret = stt_set_private_data(stt, private_key, data);
939         if (0 != ret) {
940                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set private data, ret(%d), key(%s)", ret, private_key);
941         }
942
943         free(data);
944         data = NULL;
945         free(private_key);
946         private_key = NULL;
947
948         SLOG(LOG_INFO, TAG_STTC, "======");
949         SLOG(LOG_DEBUG, TAG_STTC, " ");
950
951         return ret;
952 }
953 //LCOV_EXCL_STOP
954
955 static Eina_Bool __stt_connect_daemon(void *data)
956 {
957         stt_client_s* client = (stt_client_s*)data;
958         int ret = -1;
959
960         if (NULL == client) {
961                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available"); //LCOV_EXCL_LINE
962                 g_connect_timer = NULL;
963                 return EINA_FALSE;
964         }
965
966         if (0 == stt_client_get_size() || NULL == stt_client_get_by_uid(client->uid)) {
967                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Client has been already destroyed"); //LCOV_EXCL_LINE
968                 return EINA_FALSE;
969         }
970
971         /* Check and Set vconfkey of custom engine before sending hello */
972         if (NULL != client->current_engine_id && 0 == __stt_check_privilege_for_applaunch()) {
973                 /* Set vconfkey */
974                 ret = __stt_set_buxtonkey(client->current_engine_id);
975                 //LCOV_EXCL_START
976                 if (0 != ret) {
977                         SLOG(LOG_DEBUG, TAG_STTC, "[DEBUG] set buxtonkey Failed!!! (inside __stt_connect_daemon)");
978                         return EINA_TRUE;
979                 }
980                 //LCOV_EXCL_STOP
981         }
982
983         /* Send hello */
984         ret = stt_dbus_request_hello(client->uid);
985
986         if (0 != ret) {
987                 if (STT_ERROR_INVALID_STATE == ret) {
988                         g_connect_timer = NULL;
989                         return EINA_FALSE;
990                 }
991                 return EINA_TRUE;
992         }
993
994         g_connect_timer = NULL;
995         SLOG(LOG_INFO, TAG_STTC, "===== Connect stt-service");
996
997         /* request initialization */
998         bool silence_supported = false;
999         bool credential_needed = false;
1000
1001         ret = stt_dbus_request_initialize(client->uid, &silence_supported, &credential_needed);
1002
1003         if (STT_ERROR_ENGINE_NOT_FOUND == ret) {
1004                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to initialize : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1005
1006                 client->reason = STT_ERROR_ENGINE_NOT_FOUND;
1007                 ecore_main_loop_thread_safe_call_async(__stt_notify_error, (void*)client);
1008
1009                 return EINA_FALSE;
1010
1011         } else if (STT_ERROR_NONE != ret) {
1012                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] Fail to connection. Retry to connect"); //LCOV_EXCL_LINE
1013                 return EINA_TRUE;
1014         } else {
1015                 /* success to connect stt-service */
1016                 client->silence_supported = silence_supported;
1017                 client->credential_needed = credential_needed;
1018                 SLOG(LOG_DEBUG, TAG_STTC, "Supported options : silence(%s), credential(%s)", silence_supported ? "support" : "no support", credential_needed ? "need" : "no need");
1019         }
1020
1021 //LCOV_EXCL_START
1022 #ifdef __UNUSED_CODES__
1023         if (NULL != client->current_engine_id) {
1024                 ret = -1;
1025                 int count = 0;
1026                 silence_supported = false;
1027                 credential_needed = false;
1028                 SLOG(LOG_DEBUG, TAG_STTC, "[WARNING] current_engine_id(%s)", client->current_engine_id);
1029
1030                 while (0 != ret) {
1031                         ret = stt_dbus_request_set_current_engine(client->uid, client->current_engine_id, &silence_supported, &credential_needed);
1032                         if (0 != ret) {
1033                                 if (STT_ERROR_TIMED_OUT != ret) {
1034                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set current engine : %s", __stt_get_error_code(ret));
1035                                         return ret;
1036                                 } else {
1037                                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1038                                         usleep(10000);
1039                                         count++;
1040                                         if (STT_RETRY_COUNT == count) {
1041                                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1042                                                 return ret;
1043                                         }
1044                                 }
1045                         } else {
1046                                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current engine uuid = %s", client->current_engine_id);
1047
1048                                 /* success to change engine */
1049                                 client->silence_supported = silence_supported;
1050                                 SLOG(LOG_DEBUG, TAG_STTC, "Supported options : silence(%s), credential(%s)", silence_supported ? "support" : "no support", credential_needed ? "need" : "no need");
1051                         }
1052                 }
1053         }
1054 #endif
1055 //LCOV_EXCL_STOP
1056         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] uid(%u)", client->uid);
1057
1058         client->before_state = client->current_state;
1059         client->current_state = STT_STATE_READY;
1060
1061         if (NULL != client->state_changed_cb) {
1062                 stt_client_use_callback(client);
1063                 client->state_changed_cb(client->stt, client->before_state,
1064                         client->current_state, client->state_changed_user_data);
1065                 stt_client_not_use_callback(client);
1066                 SLOG(LOG_DEBUG, TAG_STTC, "State changed callback is called");
1067         } else {
1068                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
1069         }
1070
1071         SLOG(LOG_INFO, TAG_STTC, "=====");
1072         SLOG(LOG_DEBUG, TAG_STTC, "  ");
1073
1074         return EINA_FALSE;
1075 }
1076
1077 int stt_prepare(stt_h stt)
1078 {
1079         stt_client_s* client = NULL;
1080         if (0 != __stt_get_feature_enabled()) {
1081                 return STT_ERROR_NOT_SUPPORTED;
1082         }
1083         if (0 != __stt_check_privilege()) {
1084                 return STT_ERROR_PERMISSION_DENIED;
1085         }
1086         if (0 != __stt_check_handle(stt, &client)) {
1087                 return STT_ERROR_INVALID_PARAMETER;
1088         }
1089
1090         SLOG(LOG_INFO, TAG_STTC, "===== Prepare STT");
1091
1092         /* check state */
1093         if (client->current_state != STT_STATE_CREATED) {
1094                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not 'CREATED'", client->current_state);
1095                 return STT_ERROR_INVALID_STATE;
1096         }
1097
1098         ecore_thread_main_loop_begin();
1099         g_connect_timer = ecore_timer_add(0.02, __stt_connect_daemon, (void*)client);
1100         ecore_thread_main_loop_end();
1101
1102         SLOG(LOG_INFO, TAG_STTC, "=====");
1103         SLOG(LOG_DEBUG, TAG_STTC, " ");
1104
1105         return STT_ERROR_NONE;
1106 }
1107
1108 int stt_unprepare(stt_h stt)
1109 {
1110         stt_client_s* client = NULL;
1111         if (0 != __stt_get_feature_enabled()) {
1112                 return STT_ERROR_NOT_SUPPORTED;
1113         }
1114         if (0 != __stt_check_privilege()) {
1115                 return STT_ERROR_PERMISSION_DENIED;
1116         }
1117         if (0 != __stt_check_handle(stt, &client)) {
1118                 return STT_ERROR_INVALID_PARAMETER;
1119         }
1120
1121         SLOG(LOG_INFO, TAG_STTC, "===== Unprepare STT");
1122
1123         /* check state */
1124         if (client->current_state != STT_STATE_READY) {
1125                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not 'READY'", client->current_state);
1126                 return STT_ERROR_INVALID_STATE;
1127         }
1128
1129         int ret = -1;
1130         int count = 0;
1131         while (0 != ret) {
1132                 ret = stt_dbus_request_finalize(client->uid);
1133                 if (0 != ret) {
1134                         //LCOV_EXCL_START
1135                         if (STT_ERROR_TIMED_OUT != ret) {
1136                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request finalize : %s", __stt_get_error_code(ret));
1137                                 break;
1138                         } else {
1139                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1140                                 usleep(10000);
1141                                 count++;
1142                                 if (STT_RETRY_COUNT == count) {
1143                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1144                                         break;
1145                                 }
1146                         }
1147                         //LCOV_EXCL_STOP
1148                 }
1149         }
1150
1151         client->internal_state = STT_INTERNAL_STATE_NONE;
1152
1153         client->before_state = client->current_state;
1154         client->current_state = STT_STATE_CREATED;
1155
1156         if (NULL != client->state_changed_cb) {
1157                 stt_client_use_callback(client);
1158                 client->state_changed_cb(client->stt, client->before_state,
1159                         client->current_state, client->state_changed_user_data);
1160                 stt_client_not_use_callback(client);
1161         } else {
1162                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
1163         }
1164
1165         if (g_connect_timer) {
1166                 ecore_timer_del(g_connect_timer);
1167                 g_connect_timer = NULL;
1168         }
1169
1170         SLOG(LOG_INFO, TAG_STTC, "=====");
1171         SLOG(LOG_DEBUG, TAG_STTC, " ");
1172
1173         return STT_ERROR_NONE;
1174 }
1175
1176 static bool __stt_config_supported_language_cb(const char* engine_id, const char* language, void* user_data)
1177 {
1178         stt_h stt = (stt_h)user_data;
1179
1180         stt_client_s* client = stt_client_get(stt);
1181         if (NULL == client) {
1182                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] A handle is not valid"); //LCOV_EXCL_LINE
1183                 return false;
1184         }
1185
1186         SLOG(LOG_INFO, TAG_STTC, "===== supported language callback");
1187
1188         /* call callback function */
1189         if (NULL != client->supported_lang_cb) {
1190                 return client->supported_lang_cb(stt, language, client->supported_lang_user_data);
1191         } else {
1192                 SLOG(LOG_WARN, TAG_STTC, "No registered callback function of supported languages"); //LCOV_EXCL_LINE
1193         }
1194
1195         return false;
1196 }
1197
1198 int stt_foreach_supported_languages(stt_h stt, stt_supported_language_cb callback, void* user_data)
1199 {
1200         stt_client_s* client = NULL;
1201         if (0 != __stt_get_feature_enabled()) {
1202                 return STT_ERROR_NOT_SUPPORTED;
1203         }
1204         if (0 != __stt_check_privilege()) {
1205                 return STT_ERROR_PERMISSION_DENIED;
1206         }
1207         if (0 != __stt_check_handle(stt, &client)) {
1208                 return STT_ERROR_INVALID_PARAMETER;
1209         }
1210
1211         SLOG(LOG_INFO, TAG_STTC, "===== Foreach Supported Language");
1212
1213         if (NULL == callback) {
1214                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1215                 return STT_ERROR_INVALID_PARAMETER;
1216         }
1217
1218         int ret;
1219         char* current_engine_id = NULL;
1220
1221         if (NULL == client->current_engine_id) {
1222                 ret = stt_config_mgr_get_engine(&current_engine_id);
1223                 if (NULL == current_engine_id) {
1224                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory or Engine id is NULL");
1225                         return STT_ERROR_OPERATION_FAILED;
1226                 }
1227                 ret = __stt_convert_config_error_code(ret);
1228                 if (0 != ret) {
1229                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get default engine id : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1230                         free(current_engine_id);
1231                         current_engine_id = NULL;
1232                         return ret;
1233                 }
1234         } else {
1235                 current_engine_id = strdup(client->current_engine_id);
1236                 //LCOV_EXCL_START
1237                 if (NULL == current_engine_id) {
1238                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory");
1239                         return STT_ERROR_OUT_OF_MEMORY;
1240                 }
1241                 //LCOV_EXCL_STOP
1242         }
1243
1244         client->supported_lang_cb = callback;
1245         client->supported_lang_user_data = user_data;
1246
1247         ret = stt_config_mgr_get_language_list(current_engine_id, __stt_config_supported_language_cb, client->stt);
1248         ret = __stt_convert_config_error_code(ret);
1249         if (0 != ret) {
1250                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get languages : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1251         }
1252
1253         if (NULL != current_engine_id) {
1254                 free(current_engine_id);
1255                 current_engine_id = NULL;
1256         }
1257
1258         client->supported_lang_cb = NULL;
1259         client->supported_lang_user_data = NULL;
1260
1261         SLOG(LOG_INFO, TAG_STTC, "=====");
1262         SLOG(LOG_DEBUG, TAG_STTC, " ");
1263
1264         return ret;
1265 }
1266
1267 int stt_get_default_language(stt_h stt, char** language)
1268 {
1269         stt_client_s* client = NULL;
1270         if (0 != __stt_get_feature_enabled()) {
1271                 return STT_ERROR_NOT_SUPPORTED;
1272         }
1273         if (0 != __stt_check_privilege()) {
1274                 return STT_ERROR_PERMISSION_DENIED;
1275         }
1276         if (0 != __stt_check_handle(stt, &client)) {
1277                 return STT_ERROR_INVALID_PARAMETER;
1278         }
1279
1280         SLOG(LOG_INFO, TAG_STTC, "===== Get Default Language");
1281
1282         if (NULL == language) {
1283                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1284                 return STT_ERROR_INVALID_PARAMETER;
1285         }
1286
1287         int ret = 0;
1288         ret = stt_config_mgr_get_default_language(language);
1289         ret = __stt_convert_config_error_code(ret);
1290         if (0 != ret) {
1291                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get default language : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1292         } else {
1293                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current language = %s", *language);
1294         }
1295
1296         SLOG(LOG_INFO, TAG_STTC, "=====");
1297         SLOG(LOG_DEBUG, TAG_STTC, " ");
1298
1299         return ret;
1300 }
1301
1302 int stt_get_state(stt_h stt, stt_state_e* state)
1303 {
1304         stt_client_s* client = NULL;
1305         if (0 != __stt_get_feature_enabled()) {
1306                 return STT_ERROR_NOT_SUPPORTED;
1307         }
1308         if (0 != __stt_check_privilege()) {
1309                 return STT_ERROR_PERMISSION_DENIED;
1310         }
1311         if (0 != __stt_check_handle(stt, &client)) {
1312                 return STT_ERROR_INVALID_PARAMETER;
1313         }
1314
1315         if (NULL == state) {
1316                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1317                 return STT_ERROR_INVALID_PARAMETER;
1318         }
1319
1320         *state = client->current_state;
1321
1322         SLOG(LOG_INFO, TAG_STTC, "===== Get state(%d)", *state);
1323
1324         switch (*state) {
1325         case STT_STATE_CREATED:         SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'CREATED'");        break;
1326         case STT_STATE_READY:           SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Ready'");          break;
1327         case STT_STATE_RECORDING:       SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Recording'");      break;
1328         case STT_STATE_PROCESSING:      SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Processing'");     break;
1329         default:                        SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid value");             break;
1330         }
1331
1332         return STT_ERROR_NONE;
1333 }
1334
1335 int stt_get_error_message(stt_h stt, char** err_msg)
1336 {
1337         stt_client_s* client = NULL;
1338         if (0 != __stt_get_feature_enabled()) {
1339                 return STT_ERROR_NOT_SUPPORTED;
1340         }
1341         if (0 != __stt_check_privilege()) {
1342                 return STT_ERROR_PERMISSION_DENIED;
1343         }
1344         if (0 != __stt_check_handle(stt, &client)) {
1345                 return STT_ERROR_INVALID_PARAMETER;
1346         }
1347
1348         if (NULL == err_msg) {
1349                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1350                 return STT_ERROR_INVALID_PARAMETER;
1351         }
1352
1353         if (false == g_err_callback_status) {
1354                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] This callback should be called during an err_callback");
1355                 return STT_ERROR_OPERATION_FAILED;
1356         }
1357
1358         if (NULL != client->err_msg) {
1359                 *err_msg = strdup(client->err_msg);
1360                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Error msg (%s)", *err_msg); //LCOV_EXCL_LINE
1361         } else {
1362                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Error msg (NULL)"); //LCOV_EXCL_LINE
1363         }
1364
1365         SLOG(LOG_INFO, TAG_STTC, "====="); //LCOV_EXCL_LINE
1366         SLOG(LOG_DEBUG, TAG_STTC, " "); //LCOV_EXCL_LINE
1367
1368         return STT_ERROR_NONE;
1369 }
1370
1371 int stt_is_recognition_type_supported(stt_h stt, const char* type, bool* support)
1372 {
1373         stt_client_s* client = NULL;
1374         if (0 != __stt_get_feature_enabled()) {
1375                 return STT_ERROR_NOT_SUPPORTED;
1376         }
1377         if (0 != __stt_check_privilege()) {
1378                 return STT_ERROR_PERMISSION_DENIED;
1379         }
1380         if (0 != __stt_check_handle(stt, &client)) {
1381                 return STT_ERROR_INVALID_PARAMETER;
1382         }
1383
1384         if (NULL == type || NULL == support) {
1385                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1386                 return STT_ERROR_INVALID_PARAMETER;
1387         }
1388
1389         /* check state */
1390         if (client->current_state != STT_STATE_READY) {
1391                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1392                 return STT_ERROR_INVALID_STATE;
1393         }
1394
1395         int ret = -1;
1396         int count = 0;
1397         while (0 != ret) {
1398                 ret = stt_dbus_request_is_recognition_type_supported(client->uid, type, support);
1399                 if (0 != ret) {
1400                         //LCOV_EXCL_START
1401                         if (STT_ERROR_TIMED_OUT != ret) {
1402                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get recognition type supported : %s", __stt_get_error_code(ret));
1403                                 return ret;
1404                         } else {
1405                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1406                                 usleep(10000);
1407                                 count++;
1408                                 if (STT_RETRY_COUNT == count) {
1409                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1410                                         return ret;
1411                                 }
1412                         }
1413                         //LCOV_EXCL_STOP
1414                 } else {
1415                         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] recognition type is %s", *support ? "true " : "false");
1416                         break;
1417                 }
1418         }
1419
1420         return STT_ERROR_NONE;
1421 }
1422
1423 int stt_set_silence_detection(stt_h stt, stt_option_silence_detection_e type)
1424 {
1425         stt_client_s* client = NULL;
1426         if (0 != __stt_get_feature_enabled()) {
1427                 return STT_ERROR_NOT_SUPPORTED;
1428         }
1429         if (0 != __stt_check_privilege()) {
1430                 return STT_ERROR_PERMISSION_DENIED;
1431         }
1432         if (0 != __stt_check_handle(stt, &client)) {
1433                 return STT_ERROR_INVALID_PARAMETER;
1434         }
1435
1436         /* check state */
1437         if (client->current_state != STT_STATE_READY) {
1438                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1439                 return STT_ERROR_INVALID_STATE;
1440         }
1441
1442         SLOG(LOG_INFO, TAG_STTC, "===== Set silence detection, supported(%d), type(%d)", client->silence_supported, type);
1443
1444         if (true == client->silence_supported) {
1445                 if (type >= STT_OPTION_SILENCE_DETECTION_FALSE && type <= STT_OPTION_SILENCE_DETECTION_AUTO) {
1446                         client->silence = type;
1447                 } else {
1448                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Type is invalid");
1449                         return STT_ERROR_INVALID_PARAMETER;
1450                 }
1451         } else {
1452                 return STT_ERROR_NOT_SUPPORTED_FEATURE;
1453         }
1454
1455         return STT_ERROR_NONE;
1456 }
1457
1458 int stt_set_start_sound(stt_h stt, const char* filename)
1459 {
1460         stt_client_s* client = NULL;
1461         if (0 != __stt_get_feature_enabled()) {
1462                 return STT_ERROR_NOT_SUPPORTED;
1463         }
1464         if (0 != __stt_check_privilege()) {
1465                 return STT_ERROR_PERMISSION_DENIED;
1466         }
1467         if (0 != __stt_check_handle(stt, &client)) {
1468                 return STT_ERROR_INVALID_PARAMETER;
1469         }
1470
1471         SLOG(LOG_INFO, TAG_STTC, "===== STT SET START SOUND");
1472
1473         if (NULL == filename) {
1474                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1475                 return STT_ERROR_INVALID_PARAMETER;
1476         }
1477
1478         if (0 != access(filename, F_OK)) {
1479                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] File does not exist"); //LCOV_EXCL_LINE
1480                 return STT_ERROR_INVALID_PARAMETER;
1481         }
1482
1483         /* check state */
1484         if (client->current_state != STT_STATE_READY) {
1485                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state); //LCOV_EXCL_LINE
1486                 return STT_ERROR_INVALID_STATE;
1487         }
1488
1489         int ret = -1;
1490         int count = 0;
1491         while (0 != ret) {
1492                 ret = stt_dbus_request_set_start_sound(client->uid, filename);
1493                 if (0 != ret) {
1494                         //LCOV_EXCL_START
1495                         if (STT_ERROR_TIMED_OUT != ret) {
1496                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set start sound : %s", __stt_get_error_code(ret));
1497                                 return ret;
1498                         } else {
1499                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1500                                 usleep(10000);
1501                                 count++;
1502                                 if (STT_RETRY_COUNT == count) {
1503                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1504                                         return ret;
1505                                 }
1506                         }
1507                         //LCOV_EXCL_STOP
1508                 } else {
1509                         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Set start sound : %s", filename);
1510                         break;
1511                 }
1512         }
1513
1514         return STT_ERROR_NONE;
1515 }
1516
1517 int stt_unset_start_sound(stt_h stt)
1518 {
1519         stt_client_s* client = NULL;
1520         if (0 != __stt_get_feature_enabled()) {
1521                 return STT_ERROR_NOT_SUPPORTED;
1522         }
1523         if (0 != __stt_check_privilege()) {
1524                 return STT_ERROR_PERMISSION_DENIED;
1525         }
1526         if (0 != __stt_check_handle(stt, &client)) {
1527                 return STT_ERROR_INVALID_PARAMETER;
1528         }
1529
1530         SLOG(LOG_INFO, TAG_STTC, "===== STT UNSET START SOUND");
1531
1532         /* check state */
1533         if (client->current_state != STT_STATE_READY) {
1534                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1535                 return STT_ERROR_INVALID_STATE;
1536         }
1537
1538         int ret = -1;
1539         int count = 0;
1540         while (0 != ret) {
1541                 ret = stt_dbus_request_unset_start_sound(client->uid);
1542                 if (0 != ret) {
1543                         //LCOV_EXCL_START
1544                         if (STT_ERROR_TIMED_OUT != ret) {
1545                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to unset start sound : %s", __stt_get_error_code(ret));
1546                                 return ret;
1547                         } else {
1548                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1549                                 usleep(10000);
1550                                 count++;
1551                                 if (STT_RETRY_COUNT == count) {
1552                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1553                                         return ret;
1554                                 }
1555                         }
1556                         //LCOV_EXCL_STOP
1557                 } else {
1558                         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Unset start sound");
1559                         break;
1560                 }
1561         }
1562
1563         return STT_ERROR_NONE;
1564 }
1565
1566 int stt_set_stop_sound(stt_h stt, const char* filename)
1567 {
1568         stt_client_s* client = NULL;
1569         if (0 != __stt_get_feature_enabled()) {
1570                 return STT_ERROR_NOT_SUPPORTED;
1571         }
1572         if (0 != __stt_check_privilege()) {
1573                 return STT_ERROR_PERMISSION_DENIED;
1574         }
1575         if (0 != __stt_check_handle(stt, &client)) {
1576                 return STT_ERROR_INVALID_PARAMETER;
1577         }
1578
1579         SLOG(LOG_INFO, TAG_STTC, "===== STT SET STOP SOUND");
1580
1581         if (NULL == filename) {
1582                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1583                 return STT_ERROR_INVALID_PARAMETER;
1584         }
1585
1586         if (0 != access(filename, F_OK)) {
1587                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] File does not exist"); //LCOV_EXCL_LINE
1588                 return STT_ERROR_INVALID_PARAMETER;
1589         }
1590
1591         /* check state */
1592         if (client->current_state != STT_STATE_READY) {
1593                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state); //LCOV_EXCL_LINE
1594                 return STT_ERROR_INVALID_STATE;
1595         }
1596
1597         int ret = -1;
1598         int count = 0;
1599         while (0 != ret) {
1600                 ret = stt_dbus_request_set_stop_sound(client->uid, filename);
1601                 if (0 != ret) {
1602                         //LCOV_EXCL_START
1603                         if (STT_ERROR_TIMED_OUT != ret) {
1604                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set stop sound : %s", __stt_get_error_code(ret));
1605                                 return ret;
1606                         } else {
1607                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1608                                 usleep(10000);
1609                                 count++;
1610                                 if (STT_RETRY_COUNT == count) {
1611                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1612                                         return ret;
1613                                 }
1614                         }
1615                         //LCOV_EXCL_STOP
1616                 } else {
1617                         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Set stop sound : %s", filename);
1618                         break;
1619                 }
1620         }
1621
1622         return STT_ERROR_NONE;
1623 }
1624
1625 int stt_unset_stop_sound(stt_h stt)
1626 {
1627         stt_client_s* client = NULL;
1628         if (0 != __stt_get_feature_enabled()) {
1629                 return STT_ERROR_NOT_SUPPORTED;
1630         }
1631         if (0 != __stt_check_privilege()) {
1632                 return STT_ERROR_PERMISSION_DENIED;
1633         }
1634         if (0 != __stt_check_handle(stt, &client)) {
1635                 return STT_ERROR_INVALID_PARAMETER;
1636         }
1637
1638         SLOG(LOG_INFO, TAG_STTC, "===== STT UNSET STOP SOUND");
1639
1640         /* check state */
1641         if (client->current_state != STT_STATE_READY) {
1642                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1643                 return STT_ERROR_INVALID_STATE;
1644         }
1645
1646         int ret = -1;
1647         int count = 0;
1648         while (0 != ret) {
1649                 ret = stt_dbus_request_unset_stop_sound(client->uid);
1650                 if (0 != ret) {
1651                         //LCOV_EXCL_START
1652                         if (STT_ERROR_TIMED_OUT != ret) {
1653                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to unset stop sound : %s", __stt_get_error_code(ret));
1654                                 return ret;
1655                         } else {
1656                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1657                                 usleep(10000);
1658                                 count++;
1659                                 if (STT_RETRY_COUNT == count) {
1660                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1661                                         return ret;
1662                                 }
1663                         }
1664                         //LCOV_EXCL_STOP
1665                 } else {
1666                         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Unset stop sound");
1667                         break;
1668                 }
1669         }
1670
1671         return STT_ERROR_NONE;
1672 }
1673
1674 int stt_start(stt_h stt, const char* language, const char* type)
1675 {
1676         stt_client_s* client = NULL;
1677         if (0 != __stt_get_feature_enabled()) {
1678                 return STT_ERROR_NOT_SUPPORTED;
1679         }
1680         if (0 != __stt_check_privilege()) {
1681                 return STT_ERROR_PERMISSION_DENIED;
1682         }
1683         if (0 != __stt_check_handle(stt, &client)) {
1684                 return STT_ERROR_INVALID_PARAMETER;
1685         }
1686
1687         SLOG(LOG_INFO, TAG_STTC, "===== STT START");
1688
1689         /* check state */
1690         if (client->current_state != STT_STATE_READY) {
1691                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1692                 return STT_ERROR_INVALID_STATE;
1693         }
1694
1695         if (STT_INTERNAL_STATE_NONE != client->internal_state) {
1696                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is NOT none : %d", client->internal_state); //LCOV_EXCL_LINE
1697                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
1698         }
1699
1700         int ret = -1;
1701         char appid[1024] = {0, };
1702         ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid) - 1);
1703
1704         if ((AUL_R_OK != ret) || (0 == strlen(appid))) {
1705                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get application ID"); //LCOV_EXCL_LINE
1706         } else {
1707                 SLOG(LOG_DEBUG, TAG_STTC, "[DEBUG] Current app id is %s", appid);
1708         }
1709
1710         char* temp = NULL;
1711         if (NULL == language) {
1712                 temp = strdup("default");
1713         } else {
1714                 temp = strdup(language);
1715         }
1716
1717         if (NULL == temp) {
1718                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory");
1719                 return STT_ERROR_OUT_OF_MEMORY;
1720         }
1721
1722         if (true == client->credential_needed && NULL == client->credential) {
1723                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Do not have app credential for this engine(%s)", client->current_engine_id); //LCOV_EXCL_LINE
1724                 free(temp);
1725                 temp = NULL;
1726                 return STT_ERROR_PERMISSION_DENIED;
1727         }
1728
1729         client->internal_state = STT_INTERNAL_STATE_STARTING;
1730         ret = stt_dbus_request_start(client->uid, temp, type, client->silence, appid, client->credential);
1731         if (0 != ret) {
1732                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to start : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1733                 client->internal_state = STT_INTERNAL_STATE_NONE;
1734         } else {
1735                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Start is successful but not done");
1736         }
1737
1738         free(temp);
1739         temp = NULL;
1740
1741         SLOG(LOG_INFO, TAG_STTC, "=====");
1742         SLOG(LOG_DEBUG, TAG_STTC, " ");
1743
1744         return ret;
1745 }
1746
1747 int stt_stop(stt_h stt)
1748 {
1749         stt_client_s* client = NULL;
1750         if (0 != __stt_get_feature_enabled()) {
1751                 return STT_ERROR_NOT_SUPPORTED;
1752         }
1753         if (0 != __stt_check_privilege()) {
1754                 return STT_ERROR_PERMISSION_DENIED;
1755         }
1756         if (0 != __stt_check_handle(stt, &client)) {
1757                 return STT_ERROR_INVALID_PARAMETER;
1758         }
1759
1760         SLOG(LOG_INFO, TAG_STTC, "===== STT STOP");
1761
1762         /* check state */
1763         if (client->current_state != STT_STATE_RECORDING) {
1764                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Current state(%d) is NOT RECORDING", client->current_state); //LCOV_EXCL_LINE
1765                 return STT_ERROR_INVALID_STATE;
1766         }
1767
1768         if (STT_INTERNAL_STATE_STARTING == client->internal_state) {
1769                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STARTING : %d", client->internal_state); //LCOV_EXCL_LINE
1770                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
1771         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state) {
1772                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is CANCELING : %d", client->internal_state); //LCOV_EXCL_LINE
1773                 return STT_ERROR_IN_PROGRESS_TO_READY;
1774         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state) {
1775                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STOPPING : %d", client->internal_state); //LCOV_EXCL_LINE
1776                 return STT_ERROR_IN_PROGRESS_TO_PROCESSING;
1777         }
1778
1779         client->internal_state = STT_INTERNAL_STATE_STOPPING;
1780         int ret = stt_dbus_request_stop(client->uid);
1781         if (0 != ret) {
1782                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to stop : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1783                 client->internal_state = STT_INTERNAL_STATE_NONE;
1784         } else {
1785                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Stop is successful but not done");
1786         }
1787
1788         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1789         SLOG(LOG_DEBUG, TAG_STTC, " ");
1790
1791         return ret;
1792 }
1793
1794
1795 int stt_cancel(stt_h stt)
1796 {
1797         stt_client_s* client = NULL;
1798         if (0 != __stt_get_feature_enabled()) {
1799                 return STT_ERROR_NOT_SUPPORTED;
1800         }
1801         if (0 != __stt_check_privilege()) {
1802                 return STT_ERROR_PERMISSION_DENIED;
1803         }
1804         if (0 != __stt_check_handle(stt, &client)) {
1805                 return STT_ERROR_INVALID_PARAMETER;
1806         }
1807
1808         SLOG(LOG_INFO, TAG_STTC, "===== STT CANCEL");
1809
1810         /* check state */
1811         if (STT_STATE_RECORDING != client->current_state && STT_STATE_PROCESSING != client->current_state) {
1812                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid state : Current state(%d) is 'Ready'", client->current_state); //LCOV_EXCL_LINE
1813                 return STT_ERROR_INVALID_STATE;
1814         }
1815
1816         if (STT_INTERNAL_STATE_STARTING == client->internal_state) {
1817                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STARTING : %d", client->internal_state); //LCOV_EXCL_LINE
1818                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
1819         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state) {
1820                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STOPPING : %d", client->internal_state); //LCOV_EXCL_LINE
1821                 return STT_ERROR_IN_PROGRESS_TO_PROCESSING;
1822         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state) {
1823                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is CANCELING : %d", client->internal_state); //LCOV_EXCL_LINE
1824                 return STT_ERROR_IN_PROGRESS_TO_READY;
1825         }
1826
1827         client->internal_state = STT_INTERNAL_STATE_CANCELING;
1828         int ret = stt_dbus_request_cancel(client->uid);
1829         if (0 != ret) {
1830                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to cancel : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1831                 client->internal_state = STT_INTERNAL_STATE_NONE;
1832         } else {
1833                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Cancel is successful but not done");
1834         }
1835
1836         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1837         SLOG(LOG_DEBUG, TAG_STTC, " ");
1838
1839         return ret;
1840 }
1841
1842 int __stt_cb_set_volume(unsigned int uid, float volume)
1843 {
1844         stt_client_s* client = NULL;
1845
1846         client = stt_client_get_by_uid(uid);
1847         if (NULL == client) {
1848                 //LCOV_EXCL_START
1849                 SLOG(LOG_ERROR, TAG_STTC, "Handle is NOT valid");
1850                 return STT_ERROR_INVALID_PARAMETER;
1851                 //LCOV_EXCL_STOP
1852         }
1853
1854         if (STT_STATE_RECORDING != client->current_state) {
1855                 //LCOV_EXCL_START
1856                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Invalid state : NO 'Recording' state, cur(%d)", client->current_state);
1857                 return STT_ERROR_INVALID_STATE;
1858                 //LCOV_EXCL_STOP
1859         }
1860
1861         g_volume_db = volume;
1862         SLOG(LOG_INFO, TAG_STTC, "Set volume (%f)", g_volume_db);
1863
1864         return 0;
1865 }
1866
1867 int stt_get_recording_volume(stt_h stt, float* volume)
1868 {
1869         stt_client_s* client = NULL;
1870         if (0 != __stt_get_feature_enabled()) {
1871                 return STT_ERROR_NOT_SUPPORTED;
1872         }
1873         if (0 != __stt_check_privilege()) {
1874                 return STT_ERROR_PERMISSION_DENIED;
1875         }
1876         if (0 != __stt_check_handle(stt, &client)) {
1877                 return STT_ERROR_INVALID_PARAMETER;
1878         }
1879
1880         if (NULL == volume) {
1881                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1882                 return STT_ERROR_INVALID_PARAMETER;
1883         }
1884
1885         if (STT_STATE_RECORDING != client->current_state) {
1886                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Invalid state : NO 'Recording' state, cur(%d)", client->current_state); //LCOV_EXCL_LINE
1887                 return STT_ERROR_INVALID_STATE;
1888         }
1889
1890         *volume = g_volume_db;
1891
1892         SLOG(LOG_INFO, TAG_STTC, "Get recording volume (%f)", *volume);
1893
1894         return STT_ERROR_NONE;
1895 }
1896
1897 //LCOV_EXCL_START
1898 bool __stt_result_time_cb(int index, int event, const char* text, long start_time, long end_time, void* user_data)
1899 {
1900         stt_client_s* client = (stt_client_s*)user_data;
1901
1902         /* check handle */
1903         if (NULL == client) {
1904                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
1905                 return EINA_FALSE;
1906         }
1907
1908         if (NULL != client->result_time_cb) {
1909                 SLOG(LOG_INFO, TAG_STTC, "(%d) event(%d) text(%s) start(%ld) end(%ld)",
1910                         index, event, text, start_time, end_time);
1911                 client->result_time_cb(client->stt, index, (stt_result_time_event_e)event,
1912                         text, start_time, end_time, client->result_time_user_data);
1913         } else {
1914                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Callback is NULL");
1915                 return false;
1916         }
1917
1918         return true;
1919 }
1920 //LCOV_EXCL_STOP
1921
1922 int stt_foreach_detailed_result(stt_h stt, stt_result_time_cb callback, void* user_data)
1923 {
1924         stt_client_s* client = NULL;
1925         if (0 != __stt_get_feature_enabled()) {
1926                 return STT_ERROR_NOT_SUPPORTED;
1927         }
1928         if (0 != __stt_check_privilege()) {
1929                 return STT_ERROR_PERMISSION_DENIED;
1930         }
1931         if (0 != __stt_check_handle(stt, &client)) {
1932                 return STT_ERROR_INVALID_PARAMETER;
1933         }
1934
1935         SLOG(LOG_INFO, TAG_STTC, "===== STT FOREACH DETAILED RESULT");
1936
1937         if (NULL == callback) {
1938                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1939                 return STT_ERROR_INVALID_PARAMETER;
1940         }
1941
1942         client->result_time_cb = callback;
1943         client->result_time_user_data = user_data;
1944
1945         int ret = -1;
1946         ret = stt_config_mgr_foreach_time_info(__stt_result_time_cb, client);
1947         ret = __stt_convert_config_error_code(ret);
1948         if (0 != ret) {
1949                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to foreach time info : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1950         }
1951
1952         client->result_time_cb = NULL;
1953         client->result_time_user_data = NULL;
1954
1955         SLOG(LOG_INFO, TAG_STTC, "=====");
1956         SLOG(LOG_DEBUG, TAG_STTC, " ");
1957
1958         return ret;
1959 }
1960
1961 static void __stt_notify_error(void *data)
1962 {
1963         stt_client_s* client = (stt_client_s*)data;
1964
1965         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error from sttd");
1966
1967         /* check handle */
1968         if (NULL == client) {
1969                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid"); //LCOV_EXCL_LINE
1970                 return;
1971         }
1972
1973         if (NULL == stt_client_get_by_uid(client->uid))
1974                 return;
1975
1976         if (NULL != client->error_cb) {
1977                 stt_client_use_callback(client);
1978                 g_err_callback_status = true;
1979                 client->error_cb(client->stt, client->reason, client->error_user_data);
1980                 g_err_callback_status = false;
1981                 stt_client_not_use_callback(client);
1982                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is called : reason [%d]", client->reason);
1983         } else {
1984                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null"); //LCOV_EXCL_LINE
1985         }
1986
1987         return;
1988 }
1989
1990 int __stt_cb_error(unsigned int uid, int reason, char* err_msg)
1991 {
1992         //LCOV_EXCL_START
1993         if (-1 == uid) {
1994                 GList* client_list = NULL;
1995                 client_list = stt_client_get_client_list();
1996
1997                 GList *iter = NULL;
1998                 stt_client_s *data = NULL;
1999
2000                 if (g_list_length(client_list) > 0) {
2001                         /* Get a first item */
2002                         iter = g_list_first(client_list);
2003
2004                         while (NULL != iter) {
2005                                 data = iter->data;
2006
2007                                 data->reason = reason;
2008                                 data->internal_state = STT_INTERNAL_STATE_NONE;
2009                                 if (NULL != data->err_msg) {
2010                                         free(data->err_msg);
2011                                         data->err_msg = NULL;
2012                                 }
2013                                 if (NULL != err_msg)
2014                                         data->err_msg = strdup(err_msg);
2015
2016                                 SLOG(LOG_INFO, TAG_STTC, "internal state is initialized to 0");
2017
2018                                 if (NULL != data->error_cb) {
2019                                         ecore_main_loop_thread_safe_call_async(__stt_notify_error, data);
2020                                 } else {
2021                                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null");
2022                                 }
2023
2024                                 if (STT_ERROR_SERVICE_RESET == reason) {
2025                                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Service reset");
2026
2027                                         data->current_state = STT_STATE_CREATED;
2028                                         if (0 != stt_prepare(data->stt)) {
2029                                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare");
2030                                         }
2031                                 }
2032
2033                                 /* Next item */
2034                                 iter = g_list_next(iter);
2035                         }
2036                 }
2037                 //LCOV_EXCL_STOP
2038         } else {
2039                 stt_client_s* client = stt_client_get_by_uid(uid);
2040                 if (NULL == client) {
2041                         SLOG(LOG_ERROR, TAG_STTC, "Handle not found"); //LCOV_EXCL_LINE
2042                         return -1;
2043                 }
2044
2045                 client->reason = reason;
2046                 client->internal_state = STT_INTERNAL_STATE_NONE;
2047                 if (NULL != client->err_msg) {
2048                         free(client->err_msg);
2049                         client->err_msg = NULL;
2050                 }
2051                 if (NULL != err_msg)
2052                         client->err_msg = strdup(err_msg);
2053
2054                 SLOG(LOG_INFO, TAG_STTC, "internal state is initialized to 0");
2055
2056                 if (NULL != client->error_cb) {
2057                         ecore_main_loop_thread_safe_call_async(__stt_notify_error, client);
2058                 } else {
2059                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null");
2060                 }
2061
2062                 if (STT_ERROR_SERVICE_RESET == reason) {
2063                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Service reset"); //LCOV_EXCL_LINE
2064
2065                         client->current_state = STT_STATE_CREATED;
2066                         if (0 != stt_prepare(client->stt)) {
2067                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare"); //LCOV_EXCL_LINE
2068                         }
2069                 }
2070         }
2071
2072         return 0;
2073 }
2074
2075 static void __stt_notify_state_changed(void *data)
2076 {
2077         stt_client_s* client = (stt_client_s*)data;
2078
2079         /* check handle */
2080         if (NULL == client) {
2081                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid"); //LCOV_EXCL_LINE
2082                 return;
2083         }
2084
2085         if (NULL == stt_client_get_by_uid(client->uid)) {
2086                 return;
2087         }
2088
2089         if (STT_INTERNAL_STATE_STARTING == client->internal_state && STT_STATE_RECORDING == client->current_state) {
2090                 client->internal_state = STT_INTERNAL_STATE_NONE;
2091                 SLOG(LOG_INFO, TAG_STTC, "Internal state change to NONE");
2092         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state && STT_STATE_PROCESSING == client->current_state) {
2093                 client->internal_state = STT_INTERNAL_STATE_NONE;
2094                 SLOG(LOG_INFO, TAG_STTC, "Internal state change to NONE");
2095         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state && STT_STATE_READY == client->current_state) {
2096                 client->internal_state = STT_INTERNAL_STATE_NONE;
2097                 SLOG(LOG_INFO, TAG_STTC, "Internal state change to NONE");
2098         }
2099
2100         if (NULL != client->state_changed_cb) {
2101                 stt_client_use_callback(client);
2102                 client->state_changed_cb(client->stt, client->before_state,
2103                         client->current_state, client->state_changed_user_data);
2104                 stt_client_not_use_callback(client);
2105                 SLOG(LOG_INFO, TAG_STTC, "State changed callback is called, State(%d)", client->current_state);
2106         } else {
2107                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null, State(%d)", client->current_state); //LCOV_EXCL_LINE
2108         }
2109
2110         return;
2111 }
2112
2113 static Eina_Bool __stt_notify_result(void *data)
2114 {
2115         stt_client_s* client = (stt_client_s*)data;
2116
2117         /* check handle */
2118         if (NULL == client) {
2119                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid"); //LCOV_EXCL_LINE
2120                 return EINA_FALSE;
2121         }
2122
2123         if (NULL == stt_client_get_by_uid(client->uid)) {
2124                 return EINA_FALSE;
2125         }
2126
2127         if (NULL != client->recognition_result_cb) {
2128                 stt_client_use_callback(client);
2129                 client->recognition_result_cb(client->stt, client->event, (const char**)client->data_list, client->data_count,
2130                         client->msg, client->recognition_result_user_data);
2131                 stt_client_not_use_callback(client);
2132                 SLOG(LOG_INFO, TAG_STTC, "client recognition result callback called");
2133         } else {
2134                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] User recognition result callback is NULL");
2135         }
2136
2137         if (NULL != client->msg) {
2138                 free(client->msg);
2139                 client->msg = NULL;
2140         }
2141
2142         if (NULL != client->data_list) {
2143                 char **temp = NULL;
2144                 temp = client->data_list;
2145
2146                 int i = 0;
2147                 for (i = 0; i < client->data_count; i++) {
2148                         if (NULL != temp[i]) {
2149                                 free(temp[i]);
2150                                 temp[i] = NULL;
2151                         } else {
2152                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Result data is error"); //LCOV_EXCL_LINE
2153                         }
2154                 }
2155                 free(client->data_list);
2156                 client->data_list = NULL;
2157         }
2158
2159         client->data_count = 0;
2160
2161         stt_config_mgr_remove_time_info_file();
2162
2163         if (STT_RESULT_EVENT_FINAL_RESULT == client->event || STT_RESULT_EVENT_ERROR == client->event) {
2164                 client->before_state = client->current_state;
2165                 client->current_state = STT_STATE_READY;
2166
2167                 if (NULL != client->state_changed_cb) {
2168                         ecore_main_loop_thread_safe_call_async(__stt_notify_state_changed, client);
2169                 } else {
2170                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null"); //LCOV_EXCL_LINE
2171                 }
2172         }
2173
2174         return EINA_FALSE;
2175 }
2176
2177 int __stt_cb_result(unsigned int uid, int event, char** data, int data_count, const char* msg)
2178 {
2179         stt_client_s* client = NULL;
2180
2181         client = stt_client_get_by_uid(uid);
2182         if (NULL == client) {
2183                 SLOG(LOG_ERROR, TAG_STTC, "Handle is NOT valid"); //LCOV_EXCL_LINE
2184                 return STT_ERROR_INVALID_PARAMETER;
2185         }
2186
2187         if (NULL != msg)
2188                 SECURE_SLOG(LOG_INFO, TAG_STTC, "Recognition Result Message = %s", msg);
2189
2190         int i = 0;
2191         for (i = 0; i < data_count; i++) {
2192                 if (NULL != data[i])
2193                         SECURE_SLOG(LOG_INFO, TAG_STTC, "Recognition Result[%d] = %s", i, data[i]);
2194         }
2195
2196         if (NULL != client->recognition_result_cb) {
2197                 client->event = event;
2198                 if (NULL != msg) {
2199                         client->msg = strdup(msg);
2200                 }
2201
2202                 client->data_count = data_count;
2203
2204                 if (data_count > 0) {
2205                         char **temp = NULL;
2206                         temp = (char**)calloc(data_count, sizeof(char*));
2207                         if (NULL == temp) {
2208                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory"); //LCOV_EXCL_LINE
2209                                 return STT_ERROR_OUT_OF_MEMORY;
2210                         }
2211
2212                         for (i = 0; i < data_count; i++) {
2213                                 if (NULL != data[i])
2214                                         temp[i] = strdup(data[i]);
2215                                 else
2216                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Result data is error"); //LCOV_EXCL_LINE
2217                         }
2218
2219                         client->data_list = temp;
2220                 }
2221         } else {
2222                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] User result callback is null");
2223         }
2224
2225         __stt_notify_result(client);
2226
2227         return STT_ERROR_NONE;
2228 }
2229
2230 int __stt_cb_set_state(unsigned int uid, int state)
2231 {
2232         stt_client_s* client = stt_client_get_by_uid(uid);
2233         if (NULL == client) {
2234                 SLOG(LOG_ERROR, TAG_STTC, "Handle not found"); //LCOV_EXCL_LINE
2235                 return -1;
2236         }
2237
2238         stt_state_e state_from_daemon = (stt_state_e)state;
2239
2240         if (client->current_state == state_from_daemon) {
2241                 SLOG(LOG_DEBUG, TAG_STTC, "Current state has already been %d", client->current_state);
2242                 return 0;
2243         }
2244
2245         client->before_state = client->current_state;
2246         client->current_state = state_from_daemon;
2247
2248         ecore_main_loop_thread_safe_call_async(__stt_notify_state_changed, client);
2249         return 0;
2250 }
2251
2252 static void __stt_notify_speech_status(void *data)
2253 {
2254         stt_client_s* client = (stt_client_s*)data;
2255
2256         /* check handle */
2257         if (NULL == client) {
2258                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify speech status : A handle is not valid"); //LCOV_EXCL_LINE
2259                 return;
2260         }
2261
2262         if (NULL == stt_client_get_by_uid(client->uid)) {
2263                 return;
2264         }
2265
2266         if (NULL != client->speech_status_cb) {
2267                 stt_client_use_callback(client);
2268                 client->speech_status_cb(client->stt, client->speech_status, client->speech_status_user_data);
2269                 stt_client_not_use_callback(client);
2270                 SLOG(LOG_INFO, TAG_STTC, "Speech status callback is called"); //LCOV_EXCL_LINE
2271         } else {
2272                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Speech status callback is null"); //LCOV_EXCL_LINE
2273         }
2274
2275         return;
2276 }
2277
2278 int __stt_cb_speech_status(unsigned int uid, int status)
2279 {
2280         stt_client_s* client = stt_client_get_by_uid(uid);
2281         if (NULL == client) {
2282                 SLOG(LOG_ERROR, TAG_STTC, "Handle not found"); //LCOV_EXCL_LINE
2283                 return -1;
2284         }
2285
2286         client->speech_status = status;
2287
2288         ecore_main_loop_thread_safe_call_async(__stt_notify_speech_status, client);
2289         return 0;
2290 }
2291
2292 int stt_set_recognition_result_cb(stt_h stt, stt_recognition_result_cb callback, void* user_data)
2293 {
2294         stt_client_s* client = NULL;
2295         if (0 != __stt_get_feature_enabled()) {
2296                 return STT_ERROR_NOT_SUPPORTED;
2297         }
2298         if (0 != __stt_check_privilege()) {
2299                 return STT_ERROR_PERMISSION_DENIED;
2300         }
2301         if (0 != __stt_check_handle(stt, &client)) {
2302                 return STT_ERROR_INVALID_PARAMETER;
2303         }
2304
2305         if (callback == NULL)
2306                 return STT_ERROR_INVALID_PARAMETER;
2307
2308         if (STT_STATE_CREATED != client->current_state) {
2309                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2310                 return STT_ERROR_INVALID_STATE;
2311         }
2312
2313         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set recognition result cb");
2314
2315         client->recognition_result_cb = callback;
2316         client->recognition_result_user_data = user_data;
2317
2318         return 0;
2319 }
2320
2321 int stt_unset_recognition_result_cb(stt_h stt)
2322 {
2323         stt_client_s* client = NULL;
2324         if (0 != __stt_get_feature_enabled()) {
2325                 return STT_ERROR_NOT_SUPPORTED;
2326         }
2327         if (0 != __stt_check_privilege()) {
2328                 return STT_ERROR_PERMISSION_DENIED;
2329         }
2330         if (0 != __stt_check_handle(stt, &client)) {
2331                 return STT_ERROR_INVALID_PARAMETER;
2332         }
2333
2334         if (STT_STATE_CREATED != client->current_state) {
2335                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2336                 return STT_ERROR_INVALID_STATE;
2337         }
2338
2339         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset recognition result cb");
2340
2341         client->recognition_result_cb = NULL;
2342         client->recognition_result_user_data = NULL;
2343
2344         return 0;
2345 }
2346
2347 int stt_set_state_changed_cb(stt_h stt, stt_state_changed_cb callback, void* user_data)
2348 {
2349         stt_client_s* client = NULL;
2350         if (0 != __stt_get_feature_enabled()) {
2351                 return STT_ERROR_NOT_SUPPORTED;
2352         }
2353         if (0 != __stt_check_privilege()) {
2354                 return STT_ERROR_PERMISSION_DENIED;
2355         }
2356         if (0 != __stt_check_handle(stt, &client)) {
2357                 return STT_ERROR_INVALID_PARAMETER;
2358         }
2359
2360         if (NULL == callback)
2361                 return STT_ERROR_INVALID_PARAMETER;
2362
2363         if (STT_STATE_CREATED != client->current_state) {
2364                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2365                 return STT_ERROR_INVALID_STATE;
2366         }
2367
2368         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set state changed cb");
2369
2370         client->state_changed_cb = callback;
2371         client->state_changed_user_data = user_data;
2372
2373         return 0;
2374 }
2375
2376 int stt_unset_state_changed_cb(stt_h stt)
2377 {
2378         stt_client_s* client = NULL;
2379         if (0 != __stt_get_feature_enabled()) {
2380                 return STT_ERROR_NOT_SUPPORTED;
2381         }
2382         if (0 != __stt_check_privilege()) {
2383                 return STT_ERROR_PERMISSION_DENIED;
2384         }
2385         if (0 != __stt_check_handle(stt, &client)) {
2386                 return STT_ERROR_INVALID_PARAMETER;
2387         }
2388
2389         if (STT_STATE_CREATED != client->current_state) {
2390                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2391                 return STT_ERROR_INVALID_STATE;
2392         }
2393
2394         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset state changed cb");
2395
2396         client->state_changed_cb = NULL;
2397         client->state_changed_user_data = NULL;
2398
2399         return 0;
2400 }
2401
2402 int stt_set_error_cb(stt_h stt, stt_error_cb callback, void* user_data)
2403 {
2404         stt_client_s* client = NULL;
2405         if (0 != __stt_get_feature_enabled()) {
2406                 return STT_ERROR_NOT_SUPPORTED;
2407         }
2408         if (0 != __stt_check_privilege()) {
2409                 return STT_ERROR_PERMISSION_DENIED;
2410         }
2411         if (0 != __stt_check_handle(stt, &client)) {
2412                 return STT_ERROR_INVALID_PARAMETER;
2413         }
2414
2415         if (NULL == callback)
2416                 return STT_ERROR_INVALID_PARAMETER;
2417
2418         if (STT_STATE_CREATED != client->current_state) {
2419                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2420                 return STT_ERROR_INVALID_STATE;
2421         }
2422
2423         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set error cb");
2424
2425         client->error_cb = callback;
2426         client->error_user_data = user_data;
2427
2428         return 0;
2429 }
2430
2431 int stt_unset_error_cb(stt_h stt)
2432 {
2433         stt_client_s* client = NULL;
2434         if (0 != __stt_get_feature_enabled()) {
2435                 return STT_ERROR_NOT_SUPPORTED;
2436         }
2437         if (0 != __stt_check_privilege()) {
2438                 return STT_ERROR_PERMISSION_DENIED;
2439         }
2440         if (0 != __stt_check_handle(stt, &client)) {
2441                 return STT_ERROR_INVALID_PARAMETER;
2442         }
2443
2444         if (STT_STATE_CREATED != client->current_state) {
2445                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2446                 return STT_ERROR_INVALID_STATE;
2447         }
2448
2449         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset error cb");
2450
2451         client->error_cb = NULL;
2452         client->error_user_data = NULL;
2453
2454         return 0;
2455 }
2456
2457 int stt_set_default_language_changed_cb(stt_h stt, stt_default_language_changed_cb callback, void* user_data)
2458 {
2459         stt_client_s* client = NULL;
2460         if (0 != __stt_get_feature_enabled()) {
2461                 return STT_ERROR_NOT_SUPPORTED;
2462         }
2463         if (0 != __stt_check_privilege()) {
2464                 return STT_ERROR_PERMISSION_DENIED;
2465         }
2466         if (0 != __stt_check_handle(stt, &client)) {
2467                 return STT_ERROR_INVALID_PARAMETER;
2468         }
2469
2470         if (NULL == callback)
2471                 return STT_ERROR_INVALID_PARAMETER;
2472
2473         if (STT_STATE_CREATED != client->current_state) {
2474                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2475                 return STT_ERROR_INVALID_STATE;
2476         }
2477
2478         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set default language changed cb");
2479
2480         client->default_lang_changed_cb = callback;
2481         client->default_lang_changed_user_data = user_data;
2482
2483         return 0;
2484 }
2485
2486 int stt_unset_default_language_changed_cb(stt_h stt)
2487 {
2488         stt_client_s* client = NULL;
2489         if (0 != __stt_get_feature_enabled()) {
2490                 return STT_ERROR_NOT_SUPPORTED;
2491         }
2492         if (0 != __stt_check_privilege()) {
2493                 return STT_ERROR_PERMISSION_DENIED;
2494         }
2495         if (0 != __stt_check_handle(stt, &client)) {
2496                 return STT_ERROR_INVALID_PARAMETER;
2497         }
2498
2499         if (STT_STATE_CREATED != client->current_state) {
2500                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2501                 return STT_ERROR_INVALID_STATE;
2502         }
2503
2504         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset default language changed cb");
2505
2506         client->default_lang_changed_cb = NULL;
2507         client->default_lang_changed_user_data = NULL;
2508
2509         return 0;
2510 }
2511
2512 int stt_set_engine_changed_cb(stt_h stt, stt_engine_changed_cb callback, void* user_data)
2513 {
2514         stt_client_s* client = NULL;
2515         if (0 != __stt_get_feature_enabled()) {
2516                 return STT_ERROR_NOT_SUPPORTED;
2517         }
2518         if (0 != __stt_check_privilege()) {
2519                 return STT_ERROR_PERMISSION_DENIED;
2520         }
2521         if (0 != __stt_check_handle(stt, &client)) {
2522                 return STT_ERROR_INVALID_PARAMETER;
2523         }
2524
2525         if (NULL == callback)
2526                 return STT_ERROR_INVALID_PARAMETER;
2527
2528         if (STT_STATE_CREATED != client->current_state) {
2529                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2530                 return STT_ERROR_INVALID_STATE;
2531         }
2532
2533         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set engine changed cb");
2534
2535         client->engine_changed_cb = callback;
2536         client->engine_changed_user_data = user_data;
2537
2538         return 0;
2539 }
2540
2541 int stt_unset_engine_changed_cb(stt_h stt)
2542 {
2543         stt_client_s* client = NULL;
2544         if (0 != __stt_get_feature_enabled()) {
2545                 return STT_ERROR_NOT_SUPPORTED;
2546         }
2547         if (0 != __stt_check_privilege()) {
2548                 return STT_ERROR_PERMISSION_DENIED;
2549         }
2550         if (0 != __stt_check_handle(stt, &client)) {
2551                 return STT_ERROR_INVALID_PARAMETER;
2552         }
2553
2554         if (STT_STATE_CREATED != client->current_state) {
2555                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2556                 return STT_ERROR_INVALID_STATE;
2557         }
2558
2559         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset engine changed cb");
2560
2561         client->engine_changed_cb = NULL;
2562         client->engine_changed_user_data = NULL;
2563
2564         return 0;
2565 }
2566
2567 //LCOV_EXCL_START
2568 int stt_set_speech_status_cb(stt_h stt, stt_speech_status_cb callback, void* user_data)
2569 {
2570         stt_client_s* client = NULL;
2571         if (0 != __stt_get_feature_enabled()) {
2572                 return STT_ERROR_NOT_SUPPORTED;
2573         }
2574         if (0 != __stt_check_privilege()) {
2575                 return STT_ERROR_PERMISSION_DENIED;
2576         }
2577         if (0 != __stt_check_handle(stt, &client)) {
2578                 return STT_ERROR_INVALID_PARAMETER;
2579         }
2580
2581         if (NULL == callback)
2582                 return STT_ERROR_INVALID_PARAMETER;
2583
2584         if (STT_STATE_CREATED != client->current_state) {
2585                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2586                 return STT_ERROR_INVALID_STATE;
2587         }
2588
2589         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set speech status cb");
2590
2591         client->speech_status_cb = callback;
2592         client->speech_status_user_data = user_data;
2593
2594         return 0;
2595 }
2596
2597 int stt_unset_speech_status_cb(stt_h stt)
2598 {
2599         stt_client_s* client = NULL;
2600         if (0 != __stt_get_feature_enabled()) {
2601                 return STT_ERROR_NOT_SUPPORTED;
2602         }
2603         if (0 != __stt_check_privilege()) {
2604                 return STT_ERROR_PERMISSION_DENIED;
2605         }
2606         if (0 != __stt_check_handle(stt, &client)) {
2607                 return STT_ERROR_INVALID_PARAMETER;
2608         }
2609
2610         if (STT_STATE_CREATED != client->current_state) {
2611                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2612                 return STT_ERROR_INVALID_STATE;
2613         }
2614
2615         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset speech status cb");
2616
2617         client->speech_status_cb = NULL;
2618         client->speech_status_user_data = NULL;
2619
2620         return 0;
2621 }
2622
2623 int stt_start_file(stt_h stt, const char* language, const char* type, const char* filepath, stt_audio_type_e audio_type, int sample_rate)
2624 {
2625         stt_client_s* client = NULL;
2626         if (0 != __stt_get_feature_enabled()) {
2627                 return STT_ERROR_NOT_SUPPORTED;
2628         }
2629         if (0 != __stt_check_privilege()) {
2630                 return STT_ERROR_PERMISSION_DENIED;
2631         }
2632         if (0 != __stt_check_handle(stt, &client)) {
2633                 return STT_ERROR_INVALID_PARAMETER;
2634         }
2635         if (NULL == filepath) {
2636                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
2637                 return STT_ERROR_INVALID_PARAMETER;
2638         }
2639
2640         SLOG(LOG_INFO, TAG_STTC, "===== STT START FILE");
2641
2642         /* check state */
2643         if (client->current_state != STT_STATE_READY) {
2644                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
2645                 return STT_ERROR_INVALID_STATE;
2646         }
2647
2648         if (STT_INTERNAL_STATE_NONE != client->internal_state) {
2649                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is NOT none : %d", client->internal_state);
2650                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
2651         }
2652
2653         int ret = -1;
2654         char appid[1024] = {0, };
2655         ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid) - 1);
2656
2657         if ((AUL_R_OK != ret) || (0 == strlen(appid))) {
2658                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get application ID");
2659         } else {
2660                 SLOG(LOG_INFO, TAG_STTC, "[DEBUG] Current app id is %s", appid);
2661         }
2662
2663         char* temp = NULL;
2664         if (NULL == language) {
2665                 temp = strdup("default");
2666         } else {
2667                 temp = strdup(language);
2668         }
2669
2670         if (NULL == temp) {
2671                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory");
2672                 return STT_ERROR_OUT_OF_MEMORY;
2673         }
2674
2675         if (true == client->credential_needed && NULL == client->credential) {
2676                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Do not have app credential for this engine(%s)", client->current_engine_id);
2677                 free(temp);
2678                 temp = NULL;
2679                 return STT_ERROR_PERMISSION_DENIED;
2680         }
2681
2682         client->internal_state = STT_INTERNAL_STATE_STARTING;
2683         ret = stt_dbus_request_start_file(client->uid, temp, type, client->silence, appid, client->credential, filepath, audio_type, sample_rate);
2684         if (0 != ret) {
2685                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to start file : %s", __stt_get_error_code(ret));
2686                 client->internal_state = STT_INTERNAL_STATE_NONE;
2687         } else {
2688                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Start is successful but not done");
2689         }
2690
2691         free(temp);
2692         temp = NULL;
2693
2694         SLOG(LOG_DEBUG, TAG_STTC, "=====");
2695         SLOG(LOG_DEBUG, TAG_STTC, " ");
2696
2697         return ret;
2698 }
2699
2700 int stt_cancel_file(stt_h stt)
2701 {
2702         stt_client_s* client = NULL;
2703         if (0 != __stt_get_feature_enabled()) {
2704                 return STT_ERROR_NOT_SUPPORTED;
2705         }
2706         if (0 != __stt_check_privilege()) {
2707                 return STT_ERROR_PERMISSION_DENIED;
2708         }
2709         if (0 != __stt_check_handle(stt, &client)) {
2710                 return STT_ERROR_INVALID_PARAMETER;
2711         }
2712
2713         SLOG(LOG_INFO, TAG_STTC, "===== STT CANCEL FILE");
2714
2715         /* check state */
2716         if (STT_STATE_RECORDING != client->current_state && STT_STATE_PROCESSING != client->current_state) {
2717                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid state : Current state(%d) is 'Ready'", client->current_state);
2718                 return STT_ERROR_INVALID_STATE;
2719         }
2720
2721         if (STT_INTERNAL_STATE_STARTING == client->internal_state) {
2722                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STARTING : %d", client->internal_state);
2723                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
2724         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state) {
2725                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STOPPING : %d", client->internal_state);
2726                 return STT_ERROR_IN_PROGRESS_TO_PROCESSING;
2727         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state) {
2728                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is CANCELING : %d", client->internal_state);
2729                 return STT_ERROR_IN_PROGRESS_TO_READY;
2730         }
2731
2732         client->internal_state = STT_INTERNAL_STATE_CANCELING;
2733         int ret = stt_dbus_request_cancel_file(client->uid);
2734         if (0 != ret) {
2735                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to cancel file : %s", __stt_get_error_code(ret));
2736                 client->internal_state = STT_INTERNAL_STATE_NONE;
2737         } else {
2738                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Cancel file is successful but not done");
2739         }
2740
2741         SLOG(LOG_DEBUG, TAG_STTC, "=====");
2742         SLOG(LOG_DEBUG, TAG_STTC, " ");
2743
2744         return ret;
2745 }
2746
2747 void __sound_stream_ducking_state_changed_cb(sound_stream_ducking_h stream_ducking, bool is_ducked, void *user_data)
2748 {
2749         SLOG(LOG_DEBUG, TAG_STTC, "@@@ ducking state changed cb");
2750         SLOG(LOG_DEBUG, TAG_STTC, "[Volume] is ducked : %d", is_ducked);
2751         // ducking_flag = true;
2752         return;
2753 }
2754
2755 static char* __get_ducking_stream(sound_stream_type_e stream_type)
2756 {
2757         if (SOUND_STREAM_TYPE_MEDIA == stream_type)
2758                 return "Media stream";
2759         else if (SOUND_STREAM_TYPE_SYSTEM == stream_type)
2760                 return "System stream";
2761         else if (SOUND_STREAM_TYPE_NOTIFICATION == stream_type)
2762                 return "Notification stream";
2763         else if (SOUND_STREAM_TYPE_ALARM == stream_type)
2764                 return "Alarm stream";
2765
2766         return "Non matched stream";
2767 }
2768
2769 static int __activate_ducking_sound_stream(sound_stream_type_e stream_type, sound_stream_ducking_h stream_ducking_h, double bg_volume_ratio)
2770 {
2771         bool is_ducked = false;
2772         int ret = sound_manager_is_ducked(stream_ducking_h, &is_ducked);
2773         if (is_ducked) {
2774                 SLOG(LOG_DEBUG, TAG_STTC, "[Volume] The %s is already ducked", __get_ducking_stream(stream_type));
2775         } else {
2776                 ret = sound_manager_activate_ducking(stream_ducking_h, SND_MGR_DUCKING_DURATION, bg_volume_ratio);
2777                 if (SOUND_MANAGER_ERROR_NONE != ret) {
2778                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to activate ducking for %s", __get_ducking_stream(stream_type));
2779                 } else {
2780                         SLOG(LOG_INFO, TAG_STTC, "[Volume SUCCESS] Activate ducking for %s", __get_ducking_stream(stream_type));
2781                 }
2782         }
2783         return ret;
2784 }
2785
2786 static void __change_background_volume(stt_system_volume_event_e volume_event)
2787 {
2788         double bg_volume_ratio = 0.0;
2789
2790         if (STT_SYSTEM_VOLUME_EVENT_CHANGE_FOR_FARFIELD == volume_event) {
2791                 bg_volume_ratio = STT_BG_VOLUME_RATIO_FARFIELD;
2792         } else if (STT_SYSTEM_VOLUME_EVENT_CHANGE_FOR_NEARFIELD == volume_event) {
2793                 bg_volume_ratio = STT_BG_VOLUME_RATIO_NEARFIELD;
2794         }
2795
2796         SLOG(LOG_INFO, TAG_STTC, "[Volume] volume ratio(%lf)", bg_volume_ratio);
2797
2798         if (1.0 > bg_volume_ratio) {
2799                 __activate_ducking_sound_stream(SOUND_STREAM_TYPE_MEDIA, g_media_stream_ducking, bg_volume_ratio);
2800                 __activate_ducking_sound_stream(SOUND_STREAM_TYPE_SYSTEM, g_system_stream_ducking, bg_volume_ratio);
2801                 __activate_ducking_sound_stream(SOUND_STREAM_TYPE_NOTIFICATION, g_notification_stream_ducking, bg_volume_ratio);
2802                 __activate_ducking_sound_stream(SOUND_STREAM_TYPE_ALARM, g_alarm_stream_ducking, bg_volume_ratio);
2803         }
2804 }
2805
2806 static int __deactivate_ducking_sound_stream(sound_stream_type_e stream_type, sound_stream_ducking_h stream_ducking_h)
2807 {
2808         bool is_ducked = false;
2809         int ret = sound_manager_is_ducked(stream_ducking_h, &is_ducked);
2810         if (!is_ducked) {
2811                 SLOG(LOG_DEBUG, TAG_STTC, "[Volume] The %s is already recovered from ducking", __get_ducking_stream(stream_type));
2812         } else {
2813                 ret = sound_manager_deactivate_ducking(stream_ducking_h);
2814                 if (SOUND_MANAGER_ERROR_NONE != ret) {
2815                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to deactivate ducking for %s", __get_ducking_stream(stream_type));
2816                 } else {
2817                         SLOG(LOG_INFO, TAG_STTC, "[Volume SUCCESS] Deactivate ducking for %s", __get_ducking_stream(stream_type));
2818                 }
2819         }
2820         return ret;
2821 }
2822
2823 static void __recover_background_volume()
2824 {
2825         SLOG(LOG_INFO, TAG_STTC, "[Volume] background volume recover");
2826
2827         __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_MEDIA, g_media_stream_ducking);
2828         __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_SYSTEM, g_system_stream_ducking);
2829         __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_NOTIFICATION, g_notification_stream_ducking);
2830         __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_ALARM, g_alarm_stream_ducking);
2831 }
2832
2833 int __create_ducking_handle(void)
2834 {
2835         int ret = -1;
2836         if (NULL == g_media_stream_ducking) {
2837                 ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_MEDIA, __sound_stream_ducking_state_changed_cb, NULL, &g_media_stream_ducking);
2838                 if (SOUND_MANAGER_ERROR_NONE != ret)
2839                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to create stream ducking for type media, ret(%d)", ret);
2840         } else {
2841                 SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for media stream is already created");
2842         }
2843
2844         if (NULL == g_system_stream_ducking) {
2845                 ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_SYSTEM, __sound_stream_ducking_state_changed_cb, NULL, &g_system_stream_ducking);
2846                 if (SOUND_MANAGER_ERROR_NONE != ret)
2847                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to create stream ducking for system type, ret(%d)", ret);
2848         } else {
2849                 SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for system stream is already created");
2850         }
2851
2852         if (NULL == g_notification_stream_ducking) {
2853                 ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_NOTIFICATION, __sound_stream_ducking_state_changed_cb, NULL, &g_notification_stream_ducking);
2854                 if (SOUND_MANAGER_ERROR_NONE != ret)
2855                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to create stream ducking for notification type, ret(%d)", ret);
2856         } else {
2857                 SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for notification stream is already created");
2858         }
2859
2860         if (NULL == g_alarm_stream_ducking) {
2861                 ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_ALARM, __sound_stream_ducking_state_changed_cb, NULL, &g_alarm_stream_ducking);
2862                 if (SOUND_MANAGER_ERROR_NONE != ret)
2863                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to create stream ducking for alarm type, ret(%d)", ret);
2864         } else {
2865                 SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for alarm stream is already created");
2866         }
2867
2868         return ret;
2869 }
2870
2871 int stt_change_system_volume(stt_h stt, stt_system_volume_event_e volume_event)
2872 {
2873         SLOG(LOG_DEBUG, TAG_STTC, "[STT] Change system volume, volume_event(%d)", volume_event);
2874
2875         stt_client_s* client = NULL;
2876         if (0 != __stt_get_feature_enabled()) {
2877                 return STT_ERROR_NOT_SUPPORTED;
2878         }
2879         if (0 != __stt_check_privilege()) {
2880                 return STT_ERROR_PERMISSION_DENIED;
2881         }
2882         if (0 != __stt_check_handle(stt, &client)) {
2883                 return STT_ERROR_INVALID_PARAMETER;
2884         }
2885
2886         /* check state */
2887         if (client->current_state != STT_STATE_READY && client->current_state != STT_STATE_CREATED) {
2888                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY nor CREATED", client->current_state);
2889                 return STT_ERROR_INVALID_STATE;
2890         }
2891
2892         /* change system volume */
2893         int ret = __create_ducking_handle();
2894         if (0 != ret) {
2895                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to create volume handle");
2896         } else {
2897                 SLOG(LOG_INFO, TAG_STTC, "[DEBUG] Success to create volume handle");
2898         }
2899
2900         __change_background_volume(volume_event);
2901         return STT_ERROR_NONE;
2902 }
2903
2904 int __destroy_ducking_handle(void)
2905 {
2906         int ret = -1;
2907         if (g_media_stream_ducking) {
2908                 ret = sound_manager_destroy_stream_ducking(g_media_stream_ducking);
2909                 if (SOUND_MANAGER_ERROR_NONE != ret)
2910                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to destroy media stream ducking, ret(%d)", ret);
2911                 g_media_stream_ducking = NULL;
2912         } else {
2913                 SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for media stream is already created");
2914         }
2915
2916         if (g_system_stream_ducking) {
2917                 ret = sound_manager_destroy_stream_ducking(g_system_stream_ducking);
2918                 if (SOUND_MANAGER_ERROR_NONE != ret)
2919                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to destroy system stream ducking, ret(%d)", ret);
2920                 g_system_stream_ducking = NULL;
2921         } else {
2922                 SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for system stream is already created");
2923         }
2924
2925         if (g_notification_stream_ducking) {
2926                 ret = sound_manager_destroy_stream_ducking(g_notification_stream_ducking);
2927                 if (SOUND_MANAGER_ERROR_NONE != ret)
2928                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to destroy notification stream ducking, ret(%d)", ret);
2929                 g_notification_stream_ducking = NULL;
2930         } else {
2931                 SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for notification stream is already created");
2932         }
2933
2934         if (g_alarm_stream_ducking) {
2935                 ret = sound_manager_destroy_stream_ducking(g_alarm_stream_ducking);
2936                 if (SOUND_MANAGER_ERROR_NONE != ret)
2937                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to destroy alarm stream ducking, ret(%d)", ret);
2938                 g_alarm_stream_ducking = NULL;
2939         } else {
2940                 SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for alarm stream is already created");
2941         }
2942         return ret;
2943 }
2944
2945 int stt_recover_system_volume(stt_h stt)
2946 {
2947         SLOG(LOG_DEBUG, TAG_STTC, "[STT] recover system volume");
2948
2949         stt_client_s* client = NULL;
2950         if (0 != __stt_get_feature_enabled()) {
2951                 return STT_ERROR_NOT_SUPPORTED;
2952         }
2953         if (0 != __stt_check_privilege()) {
2954                 return STT_ERROR_PERMISSION_DENIED;
2955         }
2956         if (0 != __stt_check_handle(stt, &client)) {
2957                 return STT_ERROR_INVALID_PARAMETER;
2958         }
2959
2960         /* check state */
2961         if (client->current_state != STT_STATE_READY && client->current_state != STT_STATE_CREATED) {
2962                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY nor CREATED", client->current_state);
2963                 return STT_ERROR_INVALID_STATE;
2964         }
2965
2966         /* recover volume */
2967         __recover_background_volume();
2968         int ret = __destroy_ducking_handle();
2969         if (0 != ret) {
2970                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to destroy volume handle");
2971         } else {
2972                 SLOG(LOG_INFO, TAG_STTC, "[DEBUG] Success to destroy volume handle");
2973         }
2974
2975         return STT_ERROR_NONE;
2976 }
2977 //LCOV_EXCL_STOP