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