Change a logic for changing system volume using ducking APIs
[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(%d)", 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(%d)", (*stt)->handle);
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 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(%d)", 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 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                 ret = __stt_convert_config_error_code(ret);
1224                 if (0 != ret) {
1225                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get default engine id : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1226                         return ret;
1227                 }
1228         } else {
1229                 current_engine_id = strdup(client->current_engine_id);
1230                 //LCOV_EXCL_START
1231                 if (NULL == current_engine_id) {
1232                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory");
1233                         return STT_ERROR_OUT_OF_MEMORY;
1234                 }
1235                 //LCOV_EXCL_STOP
1236         }
1237
1238         client->supported_lang_cb = callback;
1239         client->supported_lang_user_data = user_data;
1240
1241         ret = stt_config_mgr_get_language_list(current_engine_id, __stt_config_supported_language_cb, client->stt);
1242         ret = __stt_convert_config_error_code(ret);
1243         if (0 != ret) {
1244                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get languages : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1245         }
1246
1247         if (NULL != current_engine_id) {
1248                 free(current_engine_id);
1249                 current_engine_id = NULL;
1250         }
1251
1252         client->supported_lang_cb = NULL;
1253         client->supported_lang_user_data = NULL;
1254
1255         SLOG(LOG_INFO, TAG_STTC, "=====");
1256         SLOG(LOG_DEBUG, TAG_STTC, " ");
1257
1258         return ret;
1259 }
1260
1261 int stt_get_default_language(stt_h stt, char** language)
1262 {
1263         stt_client_s* client = NULL;
1264         if (0 != __stt_get_feature_enabled()) {
1265                 return STT_ERROR_NOT_SUPPORTED;
1266         }
1267         if (0 != __stt_check_privilege()) {
1268                 return STT_ERROR_PERMISSION_DENIED;
1269         }
1270         if (0 != __stt_check_handle(stt, &client)) {
1271                 return STT_ERROR_INVALID_PARAMETER;
1272         }
1273
1274         SLOG(LOG_INFO, TAG_STTC, "===== Get Default Language");
1275
1276         if (NULL == language) {
1277                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1278                 return STT_ERROR_INVALID_PARAMETER;
1279         }
1280
1281         int ret = 0;
1282         ret = stt_config_mgr_get_default_language(language);
1283         ret = __stt_convert_config_error_code(ret);
1284         if (0 != ret) {
1285                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get default language : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1286         } else {
1287                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current language = %s", *language);
1288         }
1289
1290         SLOG(LOG_INFO, TAG_STTC, "=====");
1291         SLOG(LOG_DEBUG, TAG_STTC, " ");
1292
1293         return ret;
1294 }
1295
1296 int stt_get_state(stt_h stt, stt_state_e* state)
1297 {
1298         stt_client_s* client = NULL;
1299         if (0 != __stt_get_feature_enabled()) {
1300                 return STT_ERROR_NOT_SUPPORTED;
1301         }
1302         if (0 != __stt_check_privilege()) {
1303                 return STT_ERROR_PERMISSION_DENIED;
1304         }
1305         if (0 != __stt_check_handle(stt, &client)) {
1306                 return STT_ERROR_INVALID_PARAMETER;
1307         }
1308
1309         if (NULL == state) {
1310                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1311                 return STT_ERROR_INVALID_PARAMETER;
1312         }
1313
1314         *state = client->current_state;
1315
1316         SLOG(LOG_INFO, TAG_STTC, "===== Get state(%d)", *state);
1317
1318         switch (*state) {
1319         case STT_STATE_CREATED:         SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'CREATED'");        break;
1320         case STT_STATE_READY:           SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Ready'");          break;
1321         case STT_STATE_RECORDING:       SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Recording'");      break;
1322         case STT_STATE_PROCESSING:      SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Processing'");     break;
1323         default:                        SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid value");             break;
1324         }
1325
1326         return STT_ERROR_NONE;
1327 }
1328
1329 int stt_get_error_message(stt_h stt, char** err_msg)
1330 {
1331         stt_client_s* client = NULL;
1332         if (0 != __stt_get_feature_enabled()) {
1333                 return STT_ERROR_NOT_SUPPORTED;
1334         }
1335         if (0 != __stt_check_privilege()) {
1336                 return STT_ERROR_PERMISSION_DENIED;
1337         }
1338         if (0 != __stt_check_handle(stt, &client)) {
1339                 return STT_ERROR_INVALID_PARAMETER;
1340         }
1341
1342         if (NULL == err_msg) {
1343                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1344                 return STT_ERROR_INVALID_PARAMETER;
1345         }
1346
1347         if (false == g_err_callback_status) {
1348                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] This callback should be called during an err_callback");
1349                 return STT_ERROR_OPERATION_FAILED;
1350         }
1351
1352         if (NULL != client->err_msg) {
1353                 *err_msg = strdup(client->err_msg);
1354                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Error msg (%s)", *err_msg); //LCOV_EXCL_LINE
1355         } else {
1356                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Error msg (NULL)"); //LCOV_EXCL_LINE
1357         }
1358
1359         SLOG(LOG_INFO, TAG_STTC, "====="); //LCOV_EXCL_LINE
1360         SLOG(LOG_DEBUG, TAG_STTC, " "); //LCOV_EXCL_LINE
1361
1362         return STT_ERROR_NONE;
1363 }
1364
1365 int stt_is_recognition_type_supported(stt_h stt, const char* type, bool* support)
1366 {
1367         stt_client_s* client = NULL;
1368         if (0 != __stt_get_feature_enabled()) {
1369                 return STT_ERROR_NOT_SUPPORTED;
1370         }
1371         if (0 != __stt_check_privilege()) {
1372                 return STT_ERROR_PERMISSION_DENIED;
1373         }
1374         if (0 != __stt_check_handle(stt, &client)) {
1375                 return STT_ERROR_INVALID_PARAMETER;
1376         }
1377
1378         if (NULL == type || NULL == support) {
1379                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1380                 return STT_ERROR_INVALID_PARAMETER;
1381         }
1382
1383         /* check state */
1384         if (client->current_state != STT_STATE_READY) {
1385                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1386                 return STT_ERROR_INVALID_STATE;
1387         }
1388
1389         int ret = -1;
1390         int count = 0;
1391         while (0 != ret) {
1392                 ret = stt_dbus_request_is_recognition_type_supported(client->uid, type, support);
1393                 if (0 != ret) {
1394                         //LCOV_EXCL_START
1395                         if (STT_ERROR_TIMED_OUT != ret) {
1396                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get recognition type supported : %s", __stt_get_error_code(ret));
1397                                 return ret;
1398                         } else {
1399                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1400                                 usleep(10000);
1401                                 count++;
1402                                 if (STT_RETRY_COUNT == count) {
1403                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1404                                         return ret;
1405                                 }
1406                         }
1407                         //LCOV_EXCL_STOP
1408                 } else {
1409                         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] recognition type is %s", *support ? "true " : "false");
1410                         break;
1411                 }
1412         }
1413
1414         return STT_ERROR_NONE;
1415 }
1416
1417 int stt_set_silence_detection(stt_h stt, stt_option_silence_detection_e type)
1418 {
1419         stt_client_s* client = NULL;
1420         if (0 != __stt_get_feature_enabled()) {
1421                 return STT_ERROR_NOT_SUPPORTED;
1422         }
1423         if (0 != __stt_check_privilege()) {
1424                 return STT_ERROR_PERMISSION_DENIED;
1425         }
1426         if (0 != __stt_check_handle(stt, &client)) {
1427                 return STT_ERROR_INVALID_PARAMETER;
1428         }
1429
1430         /* check state */
1431         if (client->current_state != STT_STATE_READY) {
1432                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1433                 return STT_ERROR_INVALID_STATE;
1434         }
1435
1436         SLOG(LOG_INFO, TAG_STTC, "===== Set silence detection, supported(%d), type(%d)", client->silence_supported, type);
1437
1438         if (true == client->silence_supported) {
1439                 if (type >= STT_OPTION_SILENCE_DETECTION_FALSE && type <= STT_OPTION_SILENCE_DETECTION_AUTO) {
1440                         client->silence = type;
1441                 } else {
1442                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Type is invalid");
1443                         return STT_ERROR_INVALID_PARAMETER;
1444                 }
1445         } else {
1446                 return STT_ERROR_NOT_SUPPORTED_FEATURE;
1447         }
1448
1449         return STT_ERROR_NONE;
1450 }
1451
1452 int stt_set_start_sound(stt_h stt, const char* filename)
1453 {
1454         stt_client_s* client = NULL;
1455         if (0 != __stt_get_feature_enabled()) {
1456                 return STT_ERROR_NOT_SUPPORTED;
1457         }
1458         if (0 != __stt_check_privilege()) {
1459                 return STT_ERROR_PERMISSION_DENIED;
1460         }
1461         if (0 != __stt_check_handle(stt, &client)) {
1462                 return STT_ERROR_INVALID_PARAMETER;
1463         }
1464
1465         SLOG(LOG_INFO, TAG_STTC, "===== STT SET START SOUND");
1466
1467         if (NULL == filename) {
1468                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1469                 return STT_ERROR_INVALID_PARAMETER;
1470         }
1471
1472         if (0 != access(filename, F_OK)) {
1473                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] File does not exist"); //LCOV_EXCL_LINE
1474                 return STT_ERROR_INVALID_PARAMETER;
1475         }
1476
1477         /* check state */
1478         if (client->current_state != STT_STATE_READY) {
1479                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state); //LCOV_EXCL_LINE
1480                 return STT_ERROR_INVALID_STATE;
1481         }
1482
1483         int ret = -1;
1484         int count = 0;
1485         while (0 != ret) {
1486                 ret = stt_dbus_request_set_start_sound(client->uid, filename);
1487                 if (0 != ret) {
1488                         //LCOV_EXCL_START
1489                         if (STT_ERROR_TIMED_OUT != ret) {
1490                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set start sound : %s", __stt_get_error_code(ret));
1491                                 return ret;
1492                         } else {
1493                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1494                                 usleep(10000);
1495                                 count++;
1496                                 if (STT_RETRY_COUNT == count) {
1497                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1498                                         return ret;
1499                                 }
1500                         }
1501                         //LCOV_EXCL_STOP
1502                 } else {
1503                         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Set start sound : %s", filename);
1504                         break;
1505                 }
1506         }
1507
1508         return STT_ERROR_NONE;
1509 }
1510
1511 int stt_unset_start_sound(stt_h stt)
1512 {
1513         stt_client_s* client = NULL;
1514         if (0 != __stt_get_feature_enabled()) {
1515                 return STT_ERROR_NOT_SUPPORTED;
1516         }
1517         if (0 != __stt_check_privilege()) {
1518                 return STT_ERROR_PERMISSION_DENIED;
1519         }
1520         if (0 != __stt_check_handle(stt, &client)) {
1521                 return STT_ERROR_INVALID_PARAMETER;
1522         }
1523
1524         SLOG(LOG_INFO, TAG_STTC, "===== STT UNSET START SOUND");
1525
1526         /* check state */
1527         if (client->current_state != STT_STATE_READY) {
1528                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1529                 return STT_ERROR_INVALID_STATE;
1530         }
1531
1532         int ret = -1;
1533         int count = 0;
1534         while (0 != ret) {
1535                 ret = stt_dbus_request_unset_start_sound(client->uid);
1536                 if (0 != ret) {
1537                         //LCOV_EXCL_START
1538                         if (STT_ERROR_TIMED_OUT != ret) {
1539                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to unset start sound : %s", __stt_get_error_code(ret));
1540                                 return ret;
1541                         } else {
1542                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1543                                 usleep(10000);
1544                                 count++;
1545                                 if (STT_RETRY_COUNT == count) {
1546                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1547                                         return ret;
1548                                 }
1549                         }
1550                         //LCOV_EXCL_STOP
1551                 } else {
1552                         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Unset start sound");
1553                         break;
1554                 }
1555         }
1556
1557         return STT_ERROR_NONE;
1558 }
1559
1560 int stt_set_stop_sound(stt_h stt, const char* filename)
1561 {
1562         stt_client_s* client = NULL;
1563         if (0 != __stt_get_feature_enabled()) {
1564                 return STT_ERROR_NOT_SUPPORTED;
1565         }
1566         if (0 != __stt_check_privilege()) {
1567                 return STT_ERROR_PERMISSION_DENIED;
1568         }
1569         if (0 != __stt_check_handle(stt, &client)) {
1570                 return STT_ERROR_INVALID_PARAMETER;
1571         }
1572
1573         SLOG(LOG_INFO, TAG_STTC, "===== STT SET STOP SOUND");
1574
1575         if (NULL == filename) {
1576                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1577                 return STT_ERROR_INVALID_PARAMETER;
1578         }
1579
1580         if (0 != access(filename, F_OK)) {
1581                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] File does not exist"); //LCOV_EXCL_LINE
1582                 return STT_ERROR_INVALID_PARAMETER;
1583         }
1584
1585         /* check state */
1586         if (client->current_state != STT_STATE_READY) {
1587                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state); //LCOV_EXCL_LINE
1588                 return STT_ERROR_INVALID_STATE;
1589         }
1590
1591         int ret = -1;
1592         int count = 0;
1593         while (0 != ret) {
1594                 ret = stt_dbus_request_set_stop_sound(client->uid, filename);
1595                 if (0 != ret) {
1596                         //LCOV_EXCL_START
1597                         if (STT_ERROR_TIMED_OUT != ret) {
1598                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set stop sound : %s", __stt_get_error_code(ret));
1599                                 return ret;
1600                         } else {
1601                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1602                                 usleep(10000);
1603                                 count++;
1604                                 if (STT_RETRY_COUNT == count) {
1605                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1606                                         return ret;
1607                                 }
1608                         }
1609                         //LCOV_EXCL_STOP
1610                 } else {
1611                         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Set stop sound : %s", filename);
1612                         break;
1613                 }
1614         }
1615
1616         return STT_ERROR_NONE;
1617 }
1618
1619 int stt_unset_stop_sound(stt_h stt)
1620 {
1621         stt_client_s* client = NULL;
1622         if (0 != __stt_get_feature_enabled()) {
1623                 return STT_ERROR_NOT_SUPPORTED;
1624         }
1625         if (0 != __stt_check_privilege()) {
1626                 return STT_ERROR_PERMISSION_DENIED;
1627         }
1628         if (0 != __stt_check_handle(stt, &client)) {
1629                 return STT_ERROR_INVALID_PARAMETER;
1630         }
1631
1632         SLOG(LOG_INFO, TAG_STTC, "===== STT UNSET STOP SOUND");
1633
1634         /* check state */
1635         if (client->current_state != STT_STATE_READY) {
1636                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1637                 return STT_ERROR_INVALID_STATE;
1638         }
1639
1640         int ret = -1;
1641         int count = 0;
1642         while (0 != ret) {
1643                 ret = stt_dbus_request_unset_stop_sound(client->uid);
1644                 if (0 != ret) {
1645                         //LCOV_EXCL_START
1646                         if (STT_ERROR_TIMED_OUT != ret) {
1647                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to unset stop sound : %s", __stt_get_error_code(ret));
1648                                 return ret;
1649                         } else {
1650                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1651                                 usleep(10000);
1652                                 count++;
1653                                 if (STT_RETRY_COUNT == count) {
1654                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1655                                         return ret;
1656                                 }
1657                         }
1658                         //LCOV_EXCL_STOP
1659                 } else {
1660                         SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Unset stop sound");
1661                         break;
1662                 }
1663         }
1664
1665         return STT_ERROR_NONE;
1666 }
1667
1668 int stt_start(stt_h stt, const char* language, const char* type)
1669 {
1670         stt_client_s* client = NULL;
1671         if (0 != __stt_get_feature_enabled()) {
1672                 return STT_ERROR_NOT_SUPPORTED;
1673         }
1674         if (0 != __stt_check_privilege()) {
1675                 return STT_ERROR_PERMISSION_DENIED;
1676         }
1677         if (0 != __stt_check_handle(stt, &client)) {
1678                 return STT_ERROR_INVALID_PARAMETER;
1679         }
1680
1681         SLOG(LOG_INFO, TAG_STTC, "===== STT START");
1682
1683         /* check state */
1684         if (client->current_state != STT_STATE_READY) {
1685                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1686                 return STT_ERROR_INVALID_STATE;
1687         }
1688
1689         if (STT_INTERNAL_STATE_NONE != client->internal_state) {
1690                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is NOT none : %d", client->internal_state); //LCOV_EXCL_LINE
1691                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
1692         }
1693
1694         int ret = -1;
1695         char appid[1024] = {0, };
1696         ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid) - 1);
1697
1698         if ((AUL_R_OK != ret) || (0 == strlen(appid))) {
1699                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get application ID"); //LCOV_EXCL_LINE
1700         } else {
1701                 SLOG(LOG_DEBUG, TAG_STTC, "[DEBUG] Current app id is %s", appid);
1702         }
1703
1704         char* temp = NULL;
1705         if (NULL == language) {
1706                 temp = strdup("default");
1707         } else {
1708                 temp = strdup(language);
1709         }
1710
1711         if (NULL == temp) {
1712                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory");
1713                 return STT_ERROR_OUT_OF_MEMORY;
1714         }
1715
1716         if (true == client->credential_needed && NULL == client->credential) {
1717                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Do not have app credential for this engine(%s)", client->current_engine_id); //LCOV_EXCL_LINE
1718                 free(temp);
1719                 temp = NULL;
1720                 return STT_ERROR_PERMISSION_DENIED;
1721         }
1722
1723         client->internal_state = STT_INTERNAL_STATE_STARTING;
1724         ret = stt_dbus_request_start(client->uid, temp, type, client->silence, appid, client->credential);
1725         if (0 != ret) {
1726                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to start : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1727                 client->internal_state = STT_INTERNAL_STATE_NONE;
1728         } else {
1729                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Start is successful but not done");
1730         }
1731
1732         free(temp);
1733         temp = NULL;
1734
1735         SLOG(LOG_INFO, TAG_STTC, "=====");
1736         SLOG(LOG_DEBUG, TAG_STTC, " ");
1737
1738         return ret;
1739 }
1740
1741 int stt_stop(stt_h stt)
1742 {
1743         stt_client_s* client = NULL;
1744         if (0 != __stt_get_feature_enabled()) {
1745                 return STT_ERROR_NOT_SUPPORTED;
1746         }
1747         if (0 != __stt_check_privilege()) {
1748                 return STT_ERROR_PERMISSION_DENIED;
1749         }
1750         if (0 != __stt_check_handle(stt, &client)) {
1751                 return STT_ERROR_INVALID_PARAMETER;
1752         }
1753
1754         SLOG(LOG_INFO, TAG_STTC, "===== STT STOP");
1755
1756         /* check state */
1757         if (client->current_state != STT_STATE_RECORDING) {
1758                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Current state(%d) is NOT RECORDING", client->current_state); //LCOV_EXCL_LINE
1759                 return STT_ERROR_INVALID_STATE;
1760         }
1761
1762         if (STT_INTERNAL_STATE_STARTING == client->internal_state) {
1763                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STARTING : %d", client->internal_state); //LCOV_EXCL_LINE
1764                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
1765         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state) {
1766                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is CANCELING : %d", client->internal_state); //LCOV_EXCL_LINE
1767                 return STT_ERROR_IN_PROGRESS_TO_READY;
1768         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state) {
1769                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STOPPING : %d", client->internal_state); //LCOV_EXCL_LINE
1770                 return STT_ERROR_IN_PROGRESS_TO_PROCESSING;
1771         }
1772
1773         client->internal_state = STT_INTERNAL_STATE_STOPPING;
1774         int ret = stt_dbus_request_stop(client->uid);
1775         if (0 != ret) {
1776                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to stop : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1777                 client->internal_state = STT_INTERNAL_STATE_NONE;
1778         } else {
1779                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Stop is successful but not done");
1780         }
1781
1782         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1783         SLOG(LOG_DEBUG, TAG_STTC, " ");
1784
1785         return ret;
1786 }
1787
1788
1789 int stt_cancel(stt_h stt)
1790 {
1791         stt_client_s* client = NULL;
1792         if (0 != __stt_get_feature_enabled()) {
1793                 return STT_ERROR_NOT_SUPPORTED;
1794         }
1795         if (0 != __stt_check_privilege()) {
1796                 return STT_ERROR_PERMISSION_DENIED;
1797         }
1798         if (0 != __stt_check_handle(stt, &client)) {
1799                 return STT_ERROR_INVALID_PARAMETER;
1800         }
1801
1802         SLOG(LOG_INFO, TAG_STTC, "===== STT CANCEL");
1803
1804         /* check state */
1805         if (STT_STATE_RECORDING != client->current_state && STT_STATE_PROCESSING != client->current_state) {
1806                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid state : Current state(%d) is 'Ready'", client->current_state); //LCOV_EXCL_LINE
1807                 return STT_ERROR_INVALID_STATE;
1808         }
1809
1810         if (STT_INTERNAL_STATE_STARTING == client->internal_state) {
1811                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STARTING : %d", client->internal_state); //LCOV_EXCL_LINE
1812                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
1813         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state) {
1814                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STOPPING : %d", client->internal_state); //LCOV_EXCL_LINE
1815                 return STT_ERROR_IN_PROGRESS_TO_PROCESSING;
1816         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state) {
1817                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is CANCELING : %d", client->internal_state); //LCOV_EXCL_LINE
1818                 return STT_ERROR_IN_PROGRESS_TO_READY;
1819         }
1820
1821         client->internal_state = STT_INTERNAL_STATE_CANCELING;
1822         int ret = stt_dbus_request_cancel(client->uid);
1823         if (0 != ret) {
1824                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to cancel : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1825                 client->internal_state = STT_INTERNAL_STATE_NONE;
1826         } else {
1827                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Cancel is successful but not done");
1828         }
1829
1830         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1831         SLOG(LOG_DEBUG, TAG_STTC, " ");
1832
1833         return ret;
1834 }
1835
1836 int __stt_cb_set_volume(int uid, float volume)
1837 {
1838         stt_client_s* client = NULL;
1839
1840         client = stt_client_get_by_uid(uid);
1841         if (NULL == client) {
1842                 //LCOV_EXCL_START
1843                 SLOG(LOG_ERROR, TAG_STTC, "Handle is NOT valid");
1844                 return STT_ERROR_INVALID_PARAMETER;
1845                 //LCOV_EXCL_STOP
1846         }
1847
1848         if (STT_STATE_RECORDING != client->current_state) {
1849                 //LCOV_EXCL_START
1850                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Invalid state : NO 'Recording' state, cur(%d)", client->current_state);
1851                 return STT_ERROR_INVALID_STATE;
1852                 //LCOV_EXCL_STOP
1853         }
1854
1855         g_volume_db = volume;
1856         SLOG(LOG_INFO, TAG_STTC, "Set volume (%f)", g_volume_db);
1857
1858         return 0;
1859 }
1860
1861 int stt_get_recording_volume(stt_h stt, float* volume)
1862 {
1863         stt_client_s* client = NULL;
1864         if (0 != __stt_get_feature_enabled()) {
1865                 return STT_ERROR_NOT_SUPPORTED;
1866         }
1867         if (0 != __stt_check_privilege()) {
1868                 return STT_ERROR_PERMISSION_DENIED;
1869         }
1870         if (0 != __stt_check_handle(stt, &client)) {
1871                 return STT_ERROR_INVALID_PARAMETER;
1872         }
1873
1874         if (NULL == volume) {
1875                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1876                 return STT_ERROR_INVALID_PARAMETER;
1877         }
1878
1879         if (STT_STATE_RECORDING != client->current_state) {
1880                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Invalid state : NO 'Recording' state, cur(%d)", client->current_state); //LCOV_EXCL_LINE
1881                 return STT_ERROR_INVALID_STATE;
1882         }
1883
1884         *volume = g_volume_db;
1885
1886         SLOG(LOG_INFO, TAG_STTC, "Get recording volume (%f)", *volume);
1887
1888         return STT_ERROR_NONE;
1889 }
1890
1891 //LCOV_EXCL_START
1892 bool __stt_result_time_cb(int index, int event, const char* text, long start_time, long end_time, void* user_data)
1893 {
1894         stt_client_s* client = (stt_client_s*)user_data;
1895
1896         /* check handle */
1897         if (NULL == client) {
1898                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
1899                 return EINA_FALSE;
1900         }
1901
1902         if (NULL != client->result_time_cb) {
1903                 SLOG(LOG_INFO, TAG_STTC, "(%d) event(%d) text(%s) start(%ld) end(%ld)",
1904                         index, event, text, start_time, end_time);
1905                 client->result_time_cb(client->stt, index, (stt_result_time_event_e)event,
1906                         text, start_time, end_time, client->result_time_user_data);
1907         } else {
1908                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Callback is NULL");
1909                 return false;
1910         }
1911
1912         return true;
1913 }
1914 //LCOV_EXCL_STOP
1915
1916 int stt_foreach_detailed_result(stt_h stt, stt_result_time_cb callback, void* user_data)
1917 {
1918         stt_client_s* client = NULL;
1919         if (0 != __stt_get_feature_enabled()) {
1920                 return STT_ERROR_NOT_SUPPORTED;
1921         }
1922         if (0 != __stt_check_privilege()) {
1923                 return STT_ERROR_PERMISSION_DENIED;
1924         }
1925         if (0 != __stt_check_handle(stt, &client)) {
1926                 return STT_ERROR_INVALID_PARAMETER;
1927         }
1928
1929         SLOG(LOG_INFO, TAG_STTC, "===== STT FOREACH DETAILED RESULT");
1930
1931         if (NULL == callback) {
1932                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
1933                 return STT_ERROR_INVALID_PARAMETER;
1934         }
1935
1936         client->result_time_cb = callback;
1937         client->result_time_user_data = user_data;
1938
1939         int ret = -1;
1940         ret = stt_config_mgr_foreach_time_info(__stt_result_time_cb, client);
1941         ret = __stt_convert_config_error_code(ret);
1942         if (0 != ret) {
1943                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to foreach time info : %s", __stt_get_error_code(ret)); //LCOV_EXCL_LINE
1944         }
1945
1946         client->result_time_cb = NULL;
1947         client->result_time_user_data = NULL;
1948
1949         SLOG(LOG_INFO, TAG_STTC, "=====");
1950         SLOG(LOG_DEBUG, TAG_STTC, " ");
1951
1952         return ret;
1953 }
1954
1955 static void __stt_notify_error(void *data)
1956 {
1957         stt_client_s* client = (stt_client_s*)data;
1958
1959         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error from sttd");
1960
1961         /* check handle */
1962         if (NULL == client) {
1963                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid"); //LCOV_EXCL_LINE
1964                 return;
1965         }
1966
1967         if (NULL == stt_client_get_by_uid(client->uid))
1968                 return;
1969
1970         if (NULL != client->error_cb) {
1971                 stt_client_use_callback(client);
1972                 g_err_callback_status = true;
1973                 client->error_cb(client->stt, client->reason, client->error_user_data);
1974                 g_err_callback_status = false;
1975                 stt_client_not_use_callback(client);
1976                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is called : reason [%d]", client->reason);
1977         } else {
1978                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null"); //LCOV_EXCL_LINE
1979         }
1980
1981         return;
1982 }
1983
1984 int __stt_cb_error(int uid, int reason, char* err_msg)
1985 {
1986         //LCOV_EXCL_START
1987         if (-1 == uid) {
1988                 GList* client_list = NULL;
1989                 client_list = stt_client_get_client_list();
1990
1991                 GList *iter = NULL;
1992                 stt_client_s *data = NULL;
1993
1994                 if (g_list_length(client_list) > 0) {
1995                         /* Get a first item */
1996                         iter = g_list_first(client_list);
1997
1998                         while (NULL != iter) {
1999                                 data = iter->data;
2000
2001                                 data->reason = reason;
2002                                 data->internal_state = STT_INTERNAL_STATE_NONE;
2003                                 if (NULL != data->err_msg) {
2004                                         free(data->err_msg);
2005                                         data->err_msg = NULL;
2006                                 }
2007                                 if (NULL != err_msg)
2008                                         data->err_msg = strdup(err_msg);
2009
2010                                 SLOG(LOG_INFO, TAG_STTC, "internal state is initialized to 0");
2011
2012                                 if (NULL != data->error_cb) {
2013                                         ecore_main_loop_thread_safe_call_async(__stt_notify_error, data);
2014                                 } else {
2015                                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null");
2016                                 }
2017
2018                                 if (STT_ERROR_SERVICE_RESET == reason) {
2019                                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Service reset");
2020
2021                                         data->current_state = STT_STATE_CREATED;
2022                                         if (0 != stt_prepare(data->stt)) {
2023                                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare");
2024                                         }
2025                                 }
2026
2027                                 /* Next item */
2028                                 iter = g_list_next(iter);
2029                         }
2030                 }
2031                 //LCOV_EXCL_STOP
2032         } else {
2033                 stt_client_s* client = stt_client_get_by_uid(uid);
2034                 if (NULL == client) {
2035                         SLOG(LOG_ERROR, TAG_STTC, "Handle not found"); //LCOV_EXCL_LINE
2036                         return -1;
2037                 }
2038
2039                 client->reason = reason;
2040                 client->internal_state = STT_INTERNAL_STATE_NONE;
2041                 if (NULL != client->err_msg) {
2042                         free(client->err_msg);
2043                         client->err_msg = NULL;
2044                 }
2045                 if (NULL != err_msg)
2046                         client->err_msg = strdup(err_msg);
2047
2048                 SLOG(LOG_INFO, TAG_STTC, "internal state is initialized to 0");
2049
2050                 if (NULL != client->error_cb) {
2051                         ecore_main_loop_thread_safe_call_async(__stt_notify_error, client);
2052                 } else {
2053                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null");
2054                 }
2055
2056                 if (STT_ERROR_SERVICE_RESET == reason) {
2057                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Service reset"); //LCOV_EXCL_LINE
2058
2059                         client->current_state = STT_STATE_CREATED;
2060                         if (0 != stt_prepare(client->stt)) {
2061                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare"); //LCOV_EXCL_LINE
2062                         }
2063                 }
2064         }
2065
2066         return 0;
2067 }
2068
2069 static void __stt_notify_state_changed(void *data)
2070 {
2071         stt_client_s* client = (stt_client_s*)data;
2072
2073         /* check handle */
2074         if (NULL == client) {
2075                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid"); //LCOV_EXCL_LINE
2076                 return;
2077         }
2078
2079         if (NULL == stt_client_get_by_uid(client->uid)) {
2080                 return;
2081         }
2082
2083         if (STT_INTERNAL_STATE_STARTING == client->internal_state && STT_STATE_RECORDING == client->current_state) {
2084                 client->internal_state = STT_INTERNAL_STATE_NONE;
2085                 SLOG(LOG_INFO, TAG_STTC, "Internal state change to NONE");
2086         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state && STT_STATE_PROCESSING == client->current_state) {
2087                 client->internal_state = STT_INTERNAL_STATE_NONE;
2088                 SLOG(LOG_INFO, TAG_STTC, "Internal state change to NONE");
2089         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state && STT_STATE_READY == client->current_state) {
2090                 client->internal_state = STT_INTERNAL_STATE_NONE;
2091                 SLOG(LOG_INFO, TAG_STTC, "Internal state change to NONE");
2092         }
2093
2094         if (NULL != client->state_changed_cb) {
2095                 stt_client_use_callback(client);
2096                 client->state_changed_cb(client->stt, client->before_state,
2097                         client->current_state, client->state_changed_user_data);
2098                 stt_client_not_use_callback(client);
2099                 SLOG(LOG_INFO, TAG_STTC, "State changed callback is called, State(%d)", client->current_state);
2100         } else {
2101                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null, State(%d)", client->current_state); //LCOV_EXCL_LINE
2102         }
2103
2104         return;
2105 }
2106
2107 static Eina_Bool __stt_notify_result(void *data)
2108 {
2109         stt_client_s* client = (stt_client_s*)data;
2110
2111         /* check handle */
2112         if (NULL == client) {
2113                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid"); //LCOV_EXCL_LINE
2114                 return EINA_FALSE;
2115         }
2116
2117         if (NULL == stt_client_get_by_uid(client->uid)) {
2118                 return EINA_FALSE;
2119         }
2120
2121         if (NULL != client->recognition_result_cb) {
2122                 stt_client_use_callback(client);
2123                 client->recognition_result_cb(client->stt, client->event, (const char**)client->data_list, client->data_count,
2124                         client->msg, client->recognition_result_user_data);
2125                 stt_client_not_use_callback(client);
2126                 SLOG(LOG_INFO, TAG_STTC, "client recognition result callback called");
2127         } else {
2128                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] User recognition result callback is NULL");
2129         }
2130
2131         if (NULL != client->msg) {
2132                 free(client->msg);
2133                 client->msg = NULL;
2134         }
2135
2136         if (NULL != client->data_list) {
2137                 char **temp = NULL;
2138                 temp = client->data_list;
2139
2140                 int i = 0;
2141                 for (i = 0; i < client->data_count; i++) {
2142                         if (NULL != temp[i]) {
2143                                 free(temp[i]);
2144                                 temp[i] = NULL;
2145                         } else {
2146                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Result data is error"); //LCOV_EXCL_LINE
2147                         }
2148                 }
2149                 free(client->data_list);
2150                 client->data_list = NULL;
2151         }
2152
2153         client->data_count = 0;
2154
2155         stt_config_mgr_remove_time_info_file();
2156
2157         if (STT_RESULT_EVENT_FINAL_RESULT == client->event || STT_RESULT_EVENT_ERROR == client->event) {
2158                 client->before_state = client->current_state;
2159                 client->current_state = STT_STATE_READY;
2160
2161                 if (NULL != client->state_changed_cb) {
2162                         ecore_main_loop_thread_safe_call_async(__stt_notify_state_changed, client);
2163                 } else {
2164                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null"); //LCOV_EXCL_LINE
2165                 }
2166         }
2167
2168         return EINA_FALSE;
2169 }
2170
2171 int __stt_cb_result(int uid, int event, char** data, int data_count, const char* msg)
2172 {
2173         stt_client_s* client = NULL;
2174
2175         client = stt_client_get_by_uid(uid);
2176         if (NULL == client) {
2177                 SLOG(LOG_ERROR, TAG_STTC, "Handle is NOT valid"); //LCOV_EXCL_LINE
2178                 return STT_ERROR_INVALID_PARAMETER;
2179         }
2180
2181         if (NULL != msg)
2182                 SECURE_SLOG(LOG_INFO, TAG_STTC, "Recognition Result Message = %s", msg);
2183
2184         int i = 0;
2185         for (i = 0; i < data_count; i++) {
2186                 if (NULL != data[i])
2187                         SECURE_SLOG(LOG_INFO, TAG_STTC, "Recognition Result[%d] = %s", i, data[i]);
2188         }
2189
2190         if (NULL != client->recognition_result_cb) {
2191                 client->event = event;
2192                 if (NULL != msg) {
2193                         client->msg = strdup(msg);
2194                 }
2195
2196                 client->data_count = data_count;
2197
2198                 if (data_count > 0) {
2199                         char **temp = NULL;
2200                         temp = (char**)calloc(data_count, sizeof(char*));
2201                         if (NULL == temp) {
2202                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory"); //LCOV_EXCL_LINE
2203                                 return STT_ERROR_OUT_OF_MEMORY;
2204                         }
2205
2206                         for (i = 0; i < data_count; i++) {
2207                                 if (NULL != data[i])
2208                                         temp[i] = strdup(data[i]);
2209                                 else
2210                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Result data is error"); //LCOV_EXCL_LINE
2211                         }
2212
2213                         client->data_list = temp;
2214                 }
2215         } else {
2216                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] User result callback is null");
2217         }
2218
2219         __stt_notify_result(client);
2220
2221         return STT_ERROR_NONE;
2222 }
2223
2224 int __stt_cb_set_state(int uid, int state)
2225 {
2226         stt_client_s* client = stt_client_get_by_uid(uid);
2227         if (NULL == client) {
2228                 SLOG(LOG_ERROR, TAG_STTC, "Handle not found"); //LCOV_EXCL_LINE
2229                 return -1;
2230         }
2231
2232         stt_state_e state_from_daemon = (stt_state_e)state;
2233
2234         if (client->current_state == state_from_daemon) {
2235                 SLOG(LOG_DEBUG, TAG_STTC, "Current state has already been %d", client->current_state);
2236                 return 0;
2237         }
2238
2239         client->before_state = client->current_state;
2240         client->current_state = state_from_daemon;
2241
2242         ecore_main_loop_thread_safe_call_async(__stt_notify_state_changed, client);
2243         return 0;
2244 }
2245
2246 static void __stt_notify_speech_status(void *data)
2247 {
2248         stt_client_s* client = (stt_client_s*)data;
2249
2250         /* check handle */
2251         if (NULL == client) {
2252                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify speech status : A handle is not valid"); //LCOV_EXCL_LINE
2253                 return;
2254         }
2255
2256         if (NULL == stt_client_get_by_uid(client->uid)) {
2257                 return;
2258         }
2259
2260         if (NULL != client->speech_status_cb) {
2261                 stt_client_use_callback(client);
2262                 client->speech_status_cb(client->stt, client->speech_status, client->speech_status_user_data);
2263                 stt_client_not_use_callback(client);
2264                 SLOG(LOG_INFO, TAG_STTC, "Speech status callback is called"); //LCOV_EXCL_LINE
2265         } else {
2266                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Speech status callback is null"); //LCOV_EXCL_LINE
2267         }
2268
2269         return;
2270 }
2271
2272 int __stt_cb_speech_status(int uid, int status)
2273 {
2274         stt_client_s* client = stt_client_get_by_uid(uid);
2275         if (NULL == client) {
2276                 SLOG(LOG_ERROR, TAG_STTC, "Handle not found"); //LCOV_EXCL_LINE
2277                 return -1;
2278         }
2279
2280         client->speech_status = status;
2281
2282         ecore_main_loop_thread_safe_call_async(__stt_notify_speech_status, client);
2283         return 0;
2284 }
2285
2286 int stt_set_recognition_result_cb(stt_h stt, stt_recognition_result_cb callback, void* user_data)
2287 {
2288         stt_client_s* client = NULL;
2289         if (0 != __stt_get_feature_enabled()) {
2290                 return STT_ERROR_NOT_SUPPORTED;
2291         }
2292         if (0 != __stt_check_privilege()) {
2293                 return STT_ERROR_PERMISSION_DENIED;
2294         }
2295         if (0 != __stt_check_handle(stt, &client)) {
2296                 return STT_ERROR_INVALID_PARAMETER;
2297         }
2298
2299         if (callback == NULL)
2300                 return STT_ERROR_INVALID_PARAMETER;
2301
2302         if (STT_STATE_CREATED != client->current_state) {
2303                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2304                 return STT_ERROR_INVALID_STATE;
2305         }
2306
2307         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set recognition result cb");
2308
2309         client->recognition_result_cb = callback;
2310         client->recognition_result_user_data = user_data;
2311
2312         return 0;
2313 }
2314
2315 int stt_unset_recognition_result_cb(stt_h stt)
2316 {
2317         stt_client_s* client = NULL;
2318         if (0 != __stt_get_feature_enabled()) {
2319                 return STT_ERROR_NOT_SUPPORTED;
2320         }
2321         if (0 != __stt_check_privilege()) {
2322                 return STT_ERROR_PERMISSION_DENIED;
2323         }
2324         if (0 != __stt_check_handle(stt, &client)) {
2325                 return STT_ERROR_INVALID_PARAMETER;
2326         }
2327
2328         if (STT_STATE_CREATED != client->current_state) {
2329                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2330                 return STT_ERROR_INVALID_STATE;
2331         }
2332
2333         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset recognition result cb");
2334
2335         client->recognition_result_cb = NULL;
2336         client->recognition_result_user_data = NULL;
2337
2338         return 0;
2339 }
2340
2341 int stt_set_state_changed_cb(stt_h stt, stt_state_changed_cb callback, void* user_data)
2342 {
2343         stt_client_s* client = NULL;
2344         if (0 != __stt_get_feature_enabled()) {
2345                 return STT_ERROR_NOT_SUPPORTED;
2346         }
2347         if (0 != __stt_check_privilege()) {
2348                 return STT_ERROR_PERMISSION_DENIED;
2349         }
2350         if (0 != __stt_check_handle(stt, &client)) {
2351                 return STT_ERROR_INVALID_PARAMETER;
2352         }
2353
2354         if (NULL == callback)
2355                 return STT_ERROR_INVALID_PARAMETER;
2356
2357         if (STT_STATE_CREATED != client->current_state) {
2358                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2359                 return STT_ERROR_INVALID_STATE;
2360         }
2361
2362         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set state changed cb");
2363
2364         client->state_changed_cb = callback;
2365         client->state_changed_user_data = user_data;
2366
2367         return 0;
2368 }
2369
2370 int stt_unset_state_changed_cb(stt_h stt)
2371 {
2372         stt_client_s* client = NULL;
2373         if (0 != __stt_get_feature_enabled()) {
2374                 return STT_ERROR_NOT_SUPPORTED;
2375         }
2376         if (0 != __stt_check_privilege()) {
2377                 return STT_ERROR_PERMISSION_DENIED;
2378         }
2379         if (0 != __stt_check_handle(stt, &client)) {
2380                 return STT_ERROR_INVALID_PARAMETER;
2381         }
2382
2383         if (STT_STATE_CREATED != client->current_state) {
2384                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2385                 return STT_ERROR_INVALID_STATE;
2386         }
2387
2388         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset state changed cb");
2389
2390         client->state_changed_cb = NULL;
2391         client->state_changed_user_data = NULL;
2392
2393         return 0;
2394 }
2395
2396 int stt_set_error_cb(stt_h stt, stt_error_cb callback, void* user_data)
2397 {
2398         stt_client_s* client = NULL;
2399         if (0 != __stt_get_feature_enabled()) {
2400                 return STT_ERROR_NOT_SUPPORTED;
2401         }
2402         if (0 != __stt_check_privilege()) {
2403                 return STT_ERROR_PERMISSION_DENIED;
2404         }
2405         if (0 != __stt_check_handle(stt, &client)) {
2406                 return STT_ERROR_INVALID_PARAMETER;
2407         }
2408
2409         if (NULL == callback)
2410                 return STT_ERROR_INVALID_PARAMETER;
2411
2412         if (STT_STATE_CREATED != client->current_state) {
2413                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2414                 return STT_ERROR_INVALID_STATE;
2415         }
2416
2417         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set error cb");
2418
2419         client->error_cb = callback;
2420         client->error_user_data = user_data;
2421
2422         return 0;
2423 }
2424
2425 int stt_unset_error_cb(stt_h stt)
2426 {
2427         stt_client_s* client = NULL;
2428         if (0 != __stt_get_feature_enabled()) {
2429                 return STT_ERROR_NOT_SUPPORTED;
2430         }
2431         if (0 != __stt_check_privilege()) {
2432                 return STT_ERROR_PERMISSION_DENIED;
2433         }
2434         if (0 != __stt_check_handle(stt, &client)) {
2435                 return STT_ERROR_INVALID_PARAMETER;
2436         }
2437
2438         if (STT_STATE_CREATED != client->current_state) {
2439                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2440                 return STT_ERROR_INVALID_STATE;
2441         }
2442
2443         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset error cb");
2444
2445         client->error_cb = NULL;
2446         client->error_user_data = NULL;
2447
2448         return 0;
2449 }
2450
2451 int stt_set_default_language_changed_cb(stt_h stt, stt_default_language_changed_cb callback, void* user_data)
2452 {
2453         stt_client_s* client = NULL;
2454         if (0 != __stt_get_feature_enabled()) {
2455                 return STT_ERROR_NOT_SUPPORTED;
2456         }
2457         if (0 != __stt_check_privilege()) {
2458                 return STT_ERROR_PERMISSION_DENIED;
2459         }
2460         if (0 != __stt_check_handle(stt, &client)) {
2461                 return STT_ERROR_INVALID_PARAMETER;
2462         }
2463
2464         if (NULL == callback)
2465                 return STT_ERROR_INVALID_PARAMETER;
2466
2467         if (STT_STATE_CREATED != client->current_state) {
2468                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2469                 return STT_ERROR_INVALID_STATE;
2470         }
2471
2472         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set default language changed cb");
2473
2474         client->default_lang_changed_cb = callback;
2475         client->default_lang_changed_user_data = user_data;
2476
2477         return 0;
2478 }
2479
2480 int stt_unset_default_language_changed_cb(stt_h stt)
2481 {
2482         stt_client_s* client = NULL;
2483         if (0 != __stt_get_feature_enabled()) {
2484                 return STT_ERROR_NOT_SUPPORTED;
2485         }
2486         if (0 != __stt_check_privilege()) {
2487                 return STT_ERROR_PERMISSION_DENIED;
2488         }
2489         if (0 != __stt_check_handle(stt, &client)) {
2490                 return STT_ERROR_INVALID_PARAMETER;
2491         }
2492
2493         if (STT_STATE_CREATED != client->current_state) {
2494                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2495                 return STT_ERROR_INVALID_STATE;
2496         }
2497
2498         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset default language changed cb");
2499
2500         client->default_lang_changed_cb = NULL;
2501         client->default_lang_changed_user_data = NULL;
2502
2503         return 0;
2504 }
2505
2506 int stt_set_engine_changed_cb(stt_h stt, stt_engine_changed_cb callback, void* user_data)
2507 {
2508         stt_client_s* client = NULL;
2509         if (0 != __stt_get_feature_enabled()) {
2510                 return STT_ERROR_NOT_SUPPORTED;
2511         }
2512         if (0 != __stt_check_privilege()) {
2513                 return STT_ERROR_PERMISSION_DENIED;
2514         }
2515         if (0 != __stt_check_handle(stt, &client)) {
2516                 return STT_ERROR_INVALID_PARAMETER;
2517         }
2518
2519         if (NULL == callback)
2520                 return STT_ERROR_INVALID_PARAMETER;
2521
2522         if (STT_STATE_CREATED != client->current_state) {
2523                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2524                 return STT_ERROR_INVALID_STATE;
2525         }
2526
2527         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set engine changed cb");
2528
2529         client->engine_changed_cb = callback;
2530         client->engine_changed_user_data = user_data;
2531
2532         return 0;
2533 }
2534
2535 int stt_unset_engine_changed_cb(stt_h stt)
2536 {
2537         stt_client_s* client = NULL;
2538         if (0 != __stt_get_feature_enabled()) {
2539                 return STT_ERROR_NOT_SUPPORTED;
2540         }
2541         if (0 != __stt_check_privilege()) {
2542                 return STT_ERROR_PERMISSION_DENIED;
2543         }
2544         if (0 != __stt_check_handle(stt, &client)) {
2545                 return STT_ERROR_INVALID_PARAMETER;
2546         }
2547
2548         if (STT_STATE_CREATED != client->current_state) {
2549                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2550                 return STT_ERROR_INVALID_STATE;
2551         }
2552
2553         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset engine changed cb");
2554
2555         client->engine_changed_cb = NULL;
2556         client->engine_changed_user_data = NULL;
2557
2558         return 0;
2559 }
2560
2561 //LCOV_EXCL_START
2562 int stt_set_speech_status_cb(stt_h stt, stt_speech_status_cb callback, void* user_data)
2563 {
2564         stt_client_s* client = NULL;
2565         if (0 != __stt_get_feature_enabled()) {
2566                 return STT_ERROR_NOT_SUPPORTED;
2567         }
2568         if (0 != __stt_check_privilege()) {
2569                 return STT_ERROR_PERMISSION_DENIED;
2570         }
2571         if (0 != __stt_check_handle(stt, &client)) {
2572                 return STT_ERROR_INVALID_PARAMETER;
2573         }
2574
2575         if (NULL == callback)
2576                 return STT_ERROR_INVALID_PARAMETER;
2577
2578         if (STT_STATE_CREATED != client->current_state) {
2579                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2580                 return STT_ERROR_INVALID_STATE;
2581         }
2582
2583         SLOG(LOG_INFO, TAG_STTC, "[INFO] Set speech status cb");
2584
2585         client->speech_status_cb = callback;
2586         client->speech_status_user_data = user_data;
2587
2588         return 0;
2589 }
2590
2591 int stt_unset_speech_status_cb(stt_h stt)
2592 {
2593         stt_client_s* client = NULL;
2594         if (0 != __stt_get_feature_enabled()) {
2595                 return STT_ERROR_NOT_SUPPORTED;
2596         }
2597         if (0 != __stt_check_privilege()) {
2598                 return STT_ERROR_PERMISSION_DENIED;
2599         }
2600         if (0 != __stt_check_handle(stt, &client)) {
2601                 return STT_ERROR_INVALID_PARAMETER;
2602         }
2603
2604         if (STT_STATE_CREATED != client->current_state) {
2605                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2606                 return STT_ERROR_INVALID_STATE;
2607         }
2608
2609         SLOG(LOG_INFO, TAG_STTC, "[INFO] Unset speech status cb");
2610
2611         client->speech_status_cb = NULL;
2612         client->speech_status_user_data = NULL;
2613
2614         return 0;
2615 }
2616
2617 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)
2618 {
2619         stt_client_s* client = NULL;
2620         if (0 != __stt_get_feature_enabled()) {
2621                 return STT_ERROR_NOT_SUPPORTED;
2622         }
2623         if (0 != __stt_check_privilege()) {
2624                 return STT_ERROR_PERMISSION_DENIED;
2625         }
2626         if (0 != __stt_check_handle(stt, &client)) {
2627                 return STT_ERROR_INVALID_PARAMETER;
2628         }
2629         if (NULL == filepath) {
2630                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
2631                 return STT_ERROR_INVALID_PARAMETER;
2632         }
2633
2634         SLOG(LOG_INFO, TAG_STTC, "===== STT START FILE");
2635
2636         /* check state */
2637         if (client->current_state != STT_STATE_READY) {
2638                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
2639                 return STT_ERROR_INVALID_STATE;
2640         }
2641
2642         if (STT_INTERNAL_STATE_NONE != client->internal_state) {
2643                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is NOT none : %d", client->internal_state);
2644                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
2645         }
2646
2647         int ret = -1;
2648         char appid[1024] = {0, };
2649         ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid) - 1);
2650
2651         if ((AUL_R_OK != ret) || (0 == strlen(appid))) {
2652                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get application ID");
2653         } else {
2654                 SLOG(LOG_INFO, TAG_STTC, "[DEBUG] Current app id is %s", appid);
2655         }
2656
2657         char* temp = NULL;
2658         if (NULL == language) {
2659                 temp = strdup("default");
2660         } else {
2661                 temp = strdup(language);
2662         }
2663
2664         if (NULL == temp) {
2665                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory");
2666                 return STT_ERROR_OUT_OF_MEMORY;
2667         }
2668
2669         if (true == client->credential_needed && NULL == client->credential) {
2670                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Do not have app credential for this engine(%s)", client->current_engine_id);
2671                 free(temp);
2672                 temp = NULL;
2673                 return STT_ERROR_PERMISSION_DENIED;
2674         }
2675
2676         client->internal_state = STT_INTERNAL_STATE_STARTING;
2677         ret = stt_dbus_request_start_file(client->uid, temp, type, client->silence, appid, client->credential, filepath, audio_type, sample_rate);
2678         if (0 != ret) {
2679                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to start file : %s", __stt_get_error_code(ret));
2680                 client->internal_state = STT_INTERNAL_STATE_NONE;
2681         } else {
2682                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Start is successful but not done");
2683         }
2684
2685         free(temp);
2686         temp = NULL;
2687
2688         SLOG(LOG_DEBUG, TAG_STTC, "=====");
2689         SLOG(LOG_DEBUG, TAG_STTC, " ");
2690
2691         return ret;
2692 }
2693
2694 int stt_cancel_file(stt_h stt)
2695 {
2696         stt_client_s* client = NULL;
2697         if (0 != __stt_get_feature_enabled()) {
2698                 return STT_ERROR_NOT_SUPPORTED;
2699         }
2700         if (0 != __stt_check_privilege()) {
2701                 return STT_ERROR_PERMISSION_DENIED;
2702         }
2703         if (0 != __stt_check_handle(stt, &client)) {
2704                 return STT_ERROR_INVALID_PARAMETER;
2705         }
2706
2707         SLOG(LOG_INFO, TAG_STTC, "===== STT CANCEL FILE");
2708
2709         /* check state */
2710         if (STT_STATE_RECORDING != client->current_state && STT_STATE_PROCESSING != client->current_state) {
2711                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid state : Current state(%d) is 'Ready'", client->current_state);
2712                 return STT_ERROR_INVALID_STATE;
2713         }
2714
2715         if (STT_INTERNAL_STATE_STARTING == client->internal_state) {
2716                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STARTING : %d", client->internal_state);
2717                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
2718         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state) {
2719                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STOPPING : %d", client->internal_state);
2720                 return STT_ERROR_IN_PROGRESS_TO_PROCESSING;
2721         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state) {
2722                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is CANCELING : %d", client->internal_state);
2723                 return STT_ERROR_IN_PROGRESS_TO_READY;
2724         }
2725
2726         client->internal_state = STT_INTERNAL_STATE_CANCELING;
2727         int ret = stt_dbus_request_cancel_file(client->uid);
2728         if (0 != ret) {
2729                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to cancel file : %s", __stt_get_error_code(ret));
2730                 client->internal_state = STT_INTERNAL_STATE_NONE;
2731         } else {
2732                 SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Cancel file is successful but not done");
2733         }
2734
2735         SLOG(LOG_DEBUG, TAG_STTC, "=====");
2736         SLOG(LOG_DEBUG, TAG_STTC, " ");
2737
2738         return ret;
2739 }
2740
2741 void __sound_stream_ducking_state_changed_cb(sound_stream_ducking_h stream_ducking, bool is_ducked, void *user_data)
2742 {
2743         SLOG(LOG_DEBUG, TAG_STTC, "@@@ ducking state changed cb");
2744         SLOG(LOG_DEBUG, TAG_STTC, "[Volume] is ducked : %d", is_ducked);
2745         // ducking_flag = true;
2746         return;
2747 }
2748
2749 static char* __get_ducking_stream(sound_stream_type_e stream_type)
2750 {
2751         if (SOUND_STREAM_TYPE_MEDIA == stream_type)
2752                 return "Media stream";
2753         else if (SOUND_STREAM_TYPE_SYSTEM == stream_type)
2754                 return "System stream";
2755         else if (SOUND_STREAM_TYPE_NOTIFICATION == stream_type)
2756                 return "Notification stream";
2757         else if (SOUND_STREAM_TYPE_ALARM == stream_type)
2758                 return "Alarm stream";
2759
2760         return "Non matched stream";
2761 }
2762
2763 static int __activate_ducking_sound_stream(sound_stream_type_e stream_type, sound_stream_ducking_h stream_ducking_h, double bg_volume_ratio)
2764 {
2765         bool is_ducked = false;
2766         int ret = sound_manager_is_ducked(stream_ducking_h, &is_ducked);
2767         if (is_ducked) {
2768                 SLOG(LOG_DEBUG, TAG_STTC, "[Volume] The %s is already ducked", __get_ducking_stream(stream_type));
2769         } else {
2770                 ret = sound_manager_activate_ducking(stream_ducking_h, SND_MGR_DUCKING_DURATION, bg_volume_ratio);
2771                 if (SOUND_MANAGER_ERROR_NONE != ret) {
2772                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to activate ducking for %s", __get_ducking_stream(stream_type));
2773                 } else {
2774                         SLOG(LOG_INFO, TAG_STTC, "[Volume SUCCESS] Activate ducking for %s", __get_ducking_stream(stream_type));
2775                 }
2776         }
2777         return ret;
2778 }
2779
2780 static void __change_background_volume(stt_system_volume_event_e volume_event)
2781 {
2782         double bg_volume_ratio = 0.0;
2783
2784         if (STT_SYSTEM_VOLUME_EVENT_CHANGE_FOR_FARFIELD == volume_event) {
2785                 bg_volume_ratio = STT_BG_VOLUME_RATIO_FARFIELD;
2786         } else if (STT_SYSTEM_VOLUME_EVENT_CHANGE_FOR_NEARFIELD == volume_event) {
2787                 bg_volume_ratio = STT_BG_VOLUME_RATIO_NEARFIELD;
2788         }
2789
2790         SLOG(LOG_INFO, TAG_STTC, "[Volume] volume ratio(%lf)", bg_volume_ratio);
2791
2792         if (1.0 > bg_volume_ratio) {
2793                 __activate_ducking_sound_stream(SOUND_STREAM_TYPE_MEDIA, g_media_stream_ducking, bg_volume_ratio);
2794                 __activate_ducking_sound_stream(SOUND_STREAM_TYPE_SYSTEM, g_system_stream_ducking, bg_volume_ratio);
2795                 __activate_ducking_sound_stream(SOUND_STREAM_TYPE_NOTIFICATION, g_notification_stream_ducking, bg_volume_ratio);
2796                 __activate_ducking_sound_stream(SOUND_STREAM_TYPE_ALARM, g_alarm_stream_ducking, bg_volume_ratio);
2797         }
2798 }
2799
2800 static int __deactivate_ducking_sound_stream(sound_stream_type_e stream_type, sound_stream_ducking_h stream_ducking_h)
2801 {
2802         bool is_ducked = false;
2803         int ret = sound_manager_is_ducked(stream_ducking_h, &is_ducked);
2804         if (!is_ducked) {
2805                 SLOG(LOG_DEBUG, TAG_STTC, "[Volume] The %s is already recovered from ducking", __get_ducking_stream(stream_type));
2806         } else {
2807                 ret = sound_manager_deactivate_ducking(stream_ducking_h);
2808                 if (SOUND_MANAGER_ERROR_NONE != ret) {
2809                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to deactivate ducking for %s", __get_ducking_stream(stream_type));
2810                 } else {
2811                         SLOG(LOG_INFO, TAG_STTC, "[Volume SUCCESS] Deactivate ducking for %s", __get_ducking_stream(stream_type));
2812                 }
2813         }
2814         return ret;
2815 }
2816
2817 static void __recover_background_volume()
2818 {
2819         SLOG(LOG_INFO, TAG_STTC, "[Volume] background volume recover");
2820
2821         __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_MEDIA, g_media_stream_ducking);
2822         __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_SYSTEM, g_system_stream_ducking);
2823         __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_NOTIFICATION, g_notification_stream_ducking);
2824         __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_ALARM, g_alarm_stream_ducking);
2825 }
2826
2827 int __create_ducking_handle(void)
2828 {
2829         int ret = -1;
2830         if (NULL == g_media_stream_ducking) {
2831                 ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_MEDIA, __sound_stream_ducking_state_changed_cb, NULL, &g_media_stream_ducking);
2832                 if (SOUND_MANAGER_ERROR_NONE != ret)
2833                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to create stream ducking for type media, ret(%d)", ret);
2834         } else {
2835                 SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for media stream is already created");
2836         }
2837
2838         if (NULL == g_system_stream_ducking) {
2839                 ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_SYSTEM, __sound_stream_ducking_state_changed_cb, NULL, &g_system_stream_ducking);
2840                 if (SOUND_MANAGER_ERROR_NONE != ret)
2841                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to create stream ducking for system type, ret(%d)", ret);
2842         } else {
2843                 SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for system stream is already created");
2844         }
2845
2846         if (NULL == g_notification_stream_ducking) {
2847                 ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_NOTIFICATION, __sound_stream_ducking_state_changed_cb, NULL, &g_notification_stream_ducking);
2848                 if (SOUND_MANAGER_ERROR_NONE != ret)
2849                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to create stream ducking for notification type, ret(%d)", ret);
2850         } else {
2851                 SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for notification stream is already created");
2852         }
2853
2854         if (NULL == g_alarm_stream_ducking) {
2855                 ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_ALARM, __sound_stream_ducking_state_changed_cb, NULL, &g_alarm_stream_ducking);
2856                 if (SOUND_MANAGER_ERROR_NONE != ret)
2857                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to create stream ducking for alarm type, ret(%d)", ret);
2858         } else {
2859                 SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for alarm stream is already created");
2860         }
2861
2862         return ret;
2863 }
2864
2865 int stt_change_system_volume(stt_h stt, stt_system_volume_event_e volume_event)
2866 {
2867         SLOG(LOG_DEBUG, TAG_STTC, "[STT] Change system volume, volume_event(%d)", volume_event);
2868
2869         stt_client_s* client = NULL;
2870         if (0 != __stt_get_feature_enabled()) {
2871                 return STT_ERROR_NOT_SUPPORTED;
2872         }
2873         if (0 != __stt_check_privilege()) {
2874                 return STT_ERROR_PERMISSION_DENIED;
2875         }
2876         if (0 != __stt_check_handle(stt, &client)) {
2877                 return STT_ERROR_INVALID_PARAMETER;
2878         }
2879
2880         /* check state */
2881         if (client->current_state != STT_STATE_READY && client->current_state != STT_STATE_CREATED) {
2882                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY nor CREATED", client->current_state);
2883                 return STT_ERROR_INVALID_STATE;
2884         }
2885
2886         /* change system volume */
2887         int ret = __create_ducking_handle();
2888         if (0 != ret) {
2889                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to create volume handle");
2890         } else {
2891                 SLOG(LOG_INFO, TAG_STTC, "[DEBUG] Success to create volume handle");
2892         }
2893
2894         __change_background_volume(volume_event);
2895         return STT_ERROR_NONE;
2896 }
2897
2898 int __destroy_ducking_handle(void)
2899 {
2900         int ret = -1;
2901         if (g_media_stream_ducking) {
2902                 ret = sound_manager_destroy_stream_ducking(g_media_stream_ducking);
2903                 if (SOUND_MANAGER_ERROR_NONE != ret)
2904                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to destroy media stream ducking, ret(%d)", ret);
2905                 g_media_stream_ducking = NULL;
2906         } else {
2907                 SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for media stream is already created");
2908         }
2909
2910         if (g_system_stream_ducking) {
2911                 ret = sound_manager_destroy_stream_ducking(g_system_stream_ducking);
2912                 if (SOUND_MANAGER_ERROR_NONE != ret)
2913                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to destroy system stream ducking, ret(%d)", ret);
2914                 g_system_stream_ducking = NULL;
2915         } else {
2916                 SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for system stream is already created");
2917         }
2918
2919         if (g_notification_stream_ducking) {
2920                 ret = sound_manager_destroy_stream_ducking(g_notification_stream_ducking);
2921                 if (SOUND_MANAGER_ERROR_NONE != ret)
2922                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to destroy notification stream ducking, ret(%d)", ret);
2923                 g_notification_stream_ducking = NULL;
2924         } else {
2925                 SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for notification stream is already created");
2926         }
2927
2928         if (g_alarm_stream_ducking) {
2929                 ret = sound_manager_destroy_stream_ducking(g_alarm_stream_ducking);
2930                 if (SOUND_MANAGER_ERROR_NONE != ret)
2931                         SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to destroy alarm stream ducking, ret(%d)", ret);
2932                 g_alarm_stream_ducking = NULL;
2933         } else {
2934                 SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for alarm stream is already created");
2935         }
2936         return ret;
2937 }
2938
2939 int stt_recover_system_volume(stt_h stt)
2940 {
2941         SLOG(LOG_DEBUG, TAG_STTC, "[STT] recover system volume");
2942
2943         stt_client_s* client = NULL;
2944         if (0 != __stt_get_feature_enabled()) {
2945                 return STT_ERROR_NOT_SUPPORTED;
2946         }
2947         if (0 != __stt_check_privilege()) {
2948                 return STT_ERROR_PERMISSION_DENIED;
2949         }
2950         if (0 != __stt_check_handle(stt, &client)) {
2951                 return STT_ERROR_INVALID_PARAMETER;
2952         }
2953
2954         /* check state */
2955         if (client->current_state != STT_STATE_READY && client->current_state != STT_STATE_CREATED) {
2956                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY nor CREATED", client->current_state);
2957                 return STT_ERROR_INVALID_STATE;
2958         }
2959
2960         /* recover volume */
2961         __recover_background_volume();
2962         int ret = __destroy_ducking_handle();
2963         if (0 != ret) {
2964                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to destroy volume handle");
2965         } else {
2966                 SLOG(LOG_INFO, TAG_STTC, "[DEBUG] Success to destroy volume handle");
2967         }
2968
2969         return STT_ERROR_NONE;
2970 }
2971 //LCOV_EXCL_STOP