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