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