From f532f6e7f49629e818d4e1aae8c17ecc36cac106 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Wed, 14 Dec 2016 10:34:24 +0900 Subject: [PATCH 01/16] Fix memory leak and Delete an unnecessary file Change-Id: I7037f7e91c98b2a0b9f75c6159778cde1fe256da Signed-off-by: sooyeon.kim --- common/stt_config_parser.c | 2 ++ server/sttd_main.c | 85 ---------------------------------------------- 2 files changed, 2 insertions(+), 85 deletions(-) delete mode 100644 server/sttd_main.c diff --git a/common/stt_config_parser.c b/common/stt_config_parser.c index 50de74c..7221d3b 100644 --- a/common/stt_config_parser.c +++ b/common/stt_config_parser.c @@ -942,6 +942,7 @@ int stt_parser_get_time_info(GSList** time_list) key = xmlGetProp(cur, (const xmlChar*)STT_TAG_TIME_COUNT); if (NULL == key) { SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_TIME_COUNT); + xmlFreeDoc(doc); return -1; } @@ -970,6 +971,7 @@ int stt_parser_get_time_info(GSList** time_list) if (NULL == temp_info) { SLOG(LOG_ERROR, stt_tag(), "[ERROR] Memory alloc error!!"); + xmlFreeDoc(doc); return -1; } diff --git a/server/sttd_main.c b/server/sttd_main.c deleted file mode 100644 index 6160f9f..0000000 --- a/server/sttd_main.c +++ /dev/null @@ -1,85 +0,0 @@ -/* -* Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* http://www.apache.org/licenses/LICENSE-2.0 -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include - -#include "stt_defs.h" -#include "stt_network.h" -#include "sttd_dbus.h" -#include "sttd_main.h" -#include "sttd_server.h" - - -#define CLIENT_CLEAN_UP_TIME 500 - -static Ecore_Timer* g_check_client_timer = NULL; - -int main(int argc, char** argv) -{ - SLOG(LOG_DEBUG, TAG_STTD, " "); - SLOG(LOG_DEBUG, TAG_STTD, " "); - SLOG(LOG_DEBUG, TAG_STTD, "===== STT Daemon Initialize"); - - if (!ecore_init()) { - SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to initialize Ecore"); - return EXIT_FAILURE; - } - - if (0 != sttd_dbus_open_connection()) { - SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to open connection"); - return EXIT_FAILURE; - } - - if (0 != sttd_initialize()) { - SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to initialize stt-daemon"); - return EXIT_FAILURE; - } - - stt_network_initialize(); - - g_check_client_timer = ecore_timer_add(CLIENT_CLEAN_UP_TIME, sttd_cleanup_client, NULL); - if (NULL == g_check_client_timer) { - SLOG(LOG_WARN, TAG_STTD, "[Main Warning] Fail to create timer of client check"); - } - - SLOG(LOG_DEBUG, TAG_STTD, "[Main] stt-daemon start..."); - - SLOG(LOG_DEBUG, TAG_STTD, "====="); - SLOG(LOG_DEBUG, TAG_STTD, " "); - SLOG(LOG_DEBUG, TAG_STTD, " "); - - ecore_main_loop_begin(); - - SLOG(LOG_DEBUG, TAG_STTD, "===== STT Daemon Finalize"); - - if (NULL != g_check_client_timer) { - ecore_timer_del(g_check_client_timer); - } - - sttd_dbus_close_connection(); - - stt_network_finalize(); - - sttd_finalize(); - - ecore_shutdown(); - - SLOG(LOG_DEBUG, TAG_STTD, "====="); - SLOG(LOG_DEBUG, TAG_STTD, " "); - SLOG(LOG_DEBUG, TAG_STTD, " "); - - return 0; -} - - - -- 2.7.4 From 2cb23fafc77fc28349b13ebce3a423ab54e17427 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Mon, 12 Dec 2016 20:09:30 +0900 Subject: [PATCH 02/16] Add an internal API for setting server Change-Id: I17e62da3ac2acf73969fc10d3f75ce23ba206b5c Signed-off-by: sooyeon.kim --- client/stt.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++- client/stt_client.c | 2 ++ client/stt_client.h | 3 +++ include/stt_internal.h | 36 ++++++++++++++++++++++++++ 4 files changed, 110 insertions(+), 1 deletion(-) diff --git a/client/stt.c b/client/stt.c index 4595139..2fdd82f 100644 --- a/client/stt.c +++ b/client/stt.c @@ -674,6 +674,11 @@ int stt_set_private_data(stt_h stt, const char* key, const char* data) return STT_ERROR_INVALID_STATE; } + if (true != client->internal && (0 == strcmp(key, "server") || 0 == strcmp(key, "rampcode") || 0 == strcmp(key, "epd"))) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] This is not an internal app"); + return STT_ERROR_INVALID_PARAMETER; + } + int ret = -1; int count = 0; while (0 != ret) { @@ -756,6 +761,69 @@ int stt_get_private_data(stt_h stt, const char* key, char** data) return STT_ERROR_NONE; } + +int stt_set_server_stt(stt_h stt, const char* key, char* user_data) +{ + int ret = -1; + stt_client_s* client = NULL; + + if (0 != __stt_get_feature_enabled()) { + return STT_ERROR_NOT_SUPPORTED; + } + if (0 != __stt_check_privilege()) { + return STT_ERROR_PERMISSION_DENIED; + } + if (0 != __stt_check_handle(stt, &client)) { + return STT_ERROR_INVALID_PARAMETER; + } + + SLOG(LOG_DEBUG, TAG_STTC, "===== Set STT server"); + + if (NULL == key || NULL == user_data) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid parameter"); + return STT_ERROR_INVALID_PARAMETER; + } + + if (STT_STATE_CREATED != client->current_state && STT_STATE_READY != client->current_state) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] The current state is invalid (%d).", client->current_state); + return STT_ERROR_INVALID_STATE; + } + + + client->internal = true; + + char* private_key = NULL; + private_key = strdup(key); + if (NULL == private_key) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory(private_key)"); + return STT_ERROR_OUT_OF_MEMORY; + } + + char* data = NULL; + data = strdup(user_data); + if (NULL == data) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory(data)"); + free(private_key); + private_key = NULL; + return STT_ERROR_OUT_OF_MEMORY; + } + + ret = stt_set_private_data(stt, private_key, data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set private data, ret(%d), key(%s)", ret, private_key); + } + + free(data); + data = NULL; + free(private_key); + private_key = NULL; + + SLOG(LOG_DEBUG, TAG_STTC, "======"); + SLOG(LOG_DEBUG, TAG_STTC, " "); + + return ret; +} + static Eina_Bool __stt_connect_daemon(void *data) { stt_client_s* client = (stt_client_s*)data; @@ -2281,4 +2349,4 @@ int stt_unset_speech_status_cb(stt_h stt) client->speech_status_user_data = NULL; return 0; -} \ No newline at end of file +} diff --git a/client/stt_client.c b/client/stt_client.c index 793bfd7..d2d04cf 100644 --- a/client/stt_client.c +++ b/client/stt_client.c @@ -94,6 +94,8 @@ int stt_client_new(stt_h* stt) client->cb_ref_count = 0; + client->internal = false; + g_client_list = g_list_append(g_client_list, client); *stt = temp; diff --git a/client/stt_client.h b/client/stt_client.h index 20c35d8..b11e164 100644 --- a/client/stt_client.h +++ b/client/stt_client.h @@ -88,6 +88,9 @@ typedef struct { /* error data */ int reason; char* err_msg; + + /* is this internal? */ + bool internal; } stt_client_s; diff --git a/include/stt_internal.h b/include/stt_internal.h index d0b0e70..5b0cc70 100644 --- a/include/stt_internal.h +++ b/include/stt_internal.h @@ -18,6 +18,7 @@ #define __STT_INTERNAL_H__ #include +#include /** * @file stt_internal.h @@ -88,6 +89,41 @@ int stt_set_speech_status_cb(stt_h stt, stt_speech_status_cb callback, void* use */ int stt_unset_speech_status_cb(stt_h stt); +/** + * @brief Sets server STT. + * @details Using this API, the application can set server STT with a @a key as a @a user_data + * The key is a private data to set STT server. + * There are 3 types of keys; "server", "rampcode" and "epd". + * "server": STT server address + * "rampcode": ASR ramp code + * "epd": A threshold for end-point detection + * + * The application can input the @a user_data corresponding to the @a key. + * "server": "qa", "sbx" + * "rampcode": "dash_dict", "dash_da" + * "epd": "100", "750", etc + * + * If the application sets those keys, it will be able to use corresponding STT engines and options. + * + * @since_tizen 3.0 + * @privilege %http://tizen.org/privilege/recorder + * + * @param[in] stt The STT handle + * @param[in] key The key + * @param[in] user_data The user data corresponding to the key + * + * @return 0 on success, otherwise a negative error value + * @retval #STT_ERROR_NONE Successful + * @retval #STT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #STT_ERROR_INVALID_STATE Invalid state + * @retval #STT_ERROR_NOT_SUPPORTED STT NOT supported + * @retval #STT_ERROR_OUT_OF_MEMORY STT Out of memory + * @retval #STT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state should be #STT_STATE_READY. + */ +int stt_set_server_stt(stt_h stt, const char* key, char* user_data); + #ifdef __cplusplus } #endif -- 2.7.4 From 931382eed914f816618db156bdde73c0fb3a76f8 Mon Sep 17 00:00:00 2001 From: Kwangyoun Kim Date: Wed, 21 Dec 2016 14:07:17 +0900 Subject: [PATCH 03/16] Change sound stream api Change-Id: I1ab134920d9f0951913965bc214a1e242e16fc95 (cherry picked from commit c52603160fb03a60e4edbf35eb1e91c73d07af57) --- server/sttd_recorder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100755 => 100644 server/sttd_recorder.c diff --git a/server/sttd_recorder.c b/server/sttd_recorder.c old mode 100755 new mode 100644 index 5172110..6b19499 --- a/server/sttd_recorder.c +++ b/server/sttd_recorder.c @@ -513,7 +513,7 @@ int sttd_recorder_start(int uid) if (SOUND_MANAGER_ERROR_NONE != ret) { SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to acquire focus : %d", ret); } else { - ret = audio_in_set_stream_info(g_recorder->audio_h, g_stream_info_h); + ret = audio_in_set_sound_stream_info(g_recorder->audio_h, g_stream_info_h); if (AUDIO_IO_ERROR_NONE != ret) { SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to set stream info"); } -- 2.7.4 From bdb295fb3d618ac64b2473843273faf0e2408d8c Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Fri, 23 Dec 2016 17:28:42 +0900 Subject: [PATCH 04/16] Change deprecated api(readdir_r -> readdir) Change-Id: I64a910b280301347bda9eb7f5a1c8de509999a06 Signed-off-by: Suyeon Hwang --- client/stt_file.c | 7 +------ common/stt_config_mgr.c | 8 +------- engine-parser/src/stt-engine-parser.c | 4 ++-- server/sttd_server.c | 8 +------- 4 files changed, 5 insertions(+), 22 deletions(-) mode change 100644 => 100755 client/stt_file.c mode change 100644 => 100755 common/stt_config_mgr.c mode change 100644 => 100755 server/sttd_server.c diff --git a/client/stt_file.c b/client/stt_file.c old mode 100644 new mode 100755 index 11b4a35..030829f --- a/client/stt_file.c +++ b/client/stt_file.c @@ -359,16 +359,11 @@ int stt_file_initialize(void) /* Get file name from default engine directory */ DIR *dp = NULL; int ret = -1; - struct dirent entry; struct dirent *dirp = NULL; dp = opendir(STT_DEFAULT_ENGINE); if (NULL != dp) { do { - ret = readdir_r(dp, &entry, &dirp); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_STTFC, "[File ERROR] Fail to read directory"); - break; - } + dirp = readdir(dp); if (NULL != dirp) { if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name)) diff --git a/common/stt_config_mgr.c b/common/stt_config_mgr.c old mode 100644 new mode 100755 index d7e3105..b7cf83b --- a/common/stt_config_mgr.c +++ b/common/stt_config_mgr.c @@ -657,8 +657,6 @@ int __stt_config_mgr_check_engine_is_valid(const char* engine_id) static void __get_engine_list(const char* directory) { DIR *dp = NULL; - int ret = -1; - struct dirent entry; struct dirent *dirp = NULL; if (NULL == directory) { @@ -669,11 +667,7 @@ static void __get_engine_list(const char* directory) dp = opendir(directory); if (NULL != dp) { do { - ret = readdir_r(dp, &entry, &dirp); - if (0 != ret) { - SLOG(LOG_ERROR, stt_tag(), "[File ERROR] Fail to read directory"); - break; - } + dirp = readdir(dp); if (NULL != dirp) { if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name)) diff --git a/engine-parser/src/stt-engine-parser.c b/engine-parser/src/stt-engine-parser.c index 52a89dd..a7d297d 100755 --- a/engine-parser/src/stt-engine-parser.c +++ b/engine-parser/src/stt-engine-parser.c @@ -150,7 +150,7 @@ static void __insert_language_from_metadata(xmlNodePtr root, const char *languag languages_node = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_LANGUAGE_SET); lang = strsep(&tmp_lang, ","); - while(NULL != lang) { + while (NULL != lang) { LOGD("lang (%s)", lang); lang_node = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_LANGUAGE); xmlNodeSetContent(lang_node, (const xmlChar*)lang); @@ -171,7 +171,7 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * uid_t uid = 0; int ret = -1; ret = pkgmgr_installer_info_get_target_uid(&uid); - if (ret < 0 ) { + if (ret < 0) { LOGE("[ERROR] Fail to get target uid"); return 0; } else { diff --git a/server/sttd_server.c b/server/sttd_server.c old mode 100644 new mode 100755 index d2f0bf2..591dd6d --- a/server/sttd_server.c +++ b/server/sttd_server.c @@ -542,9 +542,7 @@ int sttd_finalize() static void __read_proc() { DIR *dp = NULL; - struct dirent entry; struct dirent *dirp = NULL; - int ret = -1; int tmp; GList *iter = NULL; @@ -561,11 +559,7 @@ static void __read_proc() SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to open proc"); } else { do { - ret = readdir_r(dp, &entry, &dirp); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to readdir"); - break; - } + dirp = readdir(dp); if (NULL != dirp) { tmp = atoi(dirp->d_name); -- 2.7.4 From a0640209263d5040910591f9b496f824272bef01 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Fri, 23 Dec 2016 11:33:14 +0900 Subject: [PATCH 05/16] Add calling error_cb in sttd_server.c Change-Id: I08d818361a75b70d5afe03b77ef6e829dfe51711 Signed-off-by: sooyeon.kim (cherry picked from commit f3237cc62ba4490ff111b8402d1adcd71d427cc1) --- server/sttd_server.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/sttd_server.c b/server/sttd_server.c index 591dd6d..bbb6a52 100755 --- a/server/sttd_server.c +++ b/server/sttd_server.c @@ -353,6 +353,8 @@ int __server_speech_status_callback(stte_speech_status_e status, void *user_para int __server_error_callback(stte_error_e error, const char* msg) { SLOG(LOG_DEBUG, TAG_STTD, "[Server] Error Callback is called"); + ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL); + return STTD_ERROR_NONE; } -- 2.7.4 From 1f0b2eaa65e5ae437d1ded1566dd08a22c223065 Mon Sep 17 00:00:00 2001 From: Kwangyoun Kim Date: Tue, 27 Dec 2016 13:47:02 +0900 Subject: [PATCH 06/16] Add error tolerance with dbus signal handling Change-Id: I3ab7f1d3fe9626872d0ec3af41f961ec17d7373a Signed-off-by: Kwangyoun Kim (cherry picked from commit f24c0f45f107f89775d54fe03925b53a53def940) --- client/stt.c | 91 +++++++++++++++++++++++++++++++++++++++------------- client/stt_dbus.c | 35 ++++++++++++++++++-- server/sttd_server.c | 41 ----------------------- 3 files changed, 101 insertions(+), 66 deletions(-) diff --git a/client/stt.c b/client/stt.c index 2fdd82f..780719e 100644 --- a/client/stt.c +++ b/client/stt.c @@ -1794,34 +1794,81 @@ static Eina_Bool __stt_notify_error(void *data) int __stt_cb_error(int uid, int reason, char* err_msg) { - stt_client_s* client = stt_client_get_by_uid(uid); - if (NULL == client) { - SLOG(LOG_ERROR, TAG_STTC, "Handle not found"); - return -1; - } + if (-1 == uid) { + GList* client_list = NULL; + client_list = stt_client_get_client_list(); - client->reason = reason; - client->internal_state = STT_INTERNAL_STATE_NONE; - if (NULL != client->err_msg) { - free(client->err_msg); - client->err_msg = NULL; - } - client->err_msg = strdup(err_msg); + GList *iter = NULL; + stt_client_s *data = NULL; - SLOG(LOG_INFO, TAG_STTC, "internal state is initialized to 0"); + if (g_list_length(client_list) > 0) { + /* Get a first item */ + iter = g_list_first(client_list); - if (NULL != client->error_cb) { - ecore_timer_add(0, __stt_notify_error, client); + while (NULL != iter) { + data = iter->data; + + data->reason = reason; + data->internal_state = STT_INTERNAL_STATE_NONE; + if (NULL != data->err_msg) { + free(data->err_msg); + data->err_msg = NULL; + } + if (NULL != err_msg) + data->err_msg = strdup(err_msg); + + SLOG(LOG_INFO, TAG_STTC, "internal state is initialized to 0"); + + if (NULL != data->error_cb) { + ecore_timer_add(0, __stt_notify_error, data); + } else { + SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null"); + } + + if (STT_ERROR_SERVICE_RESET == reason) { + SLOG(LOG_WARN, TAG_STTC, "[WARNING] Service reset"); + + data->current_state = STT_STATE_CREATED; + if (0 != stt_prepare(data->stt)) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare"); + } + } + + /* Next item */ + iter = g_list_next(iter); + } + } } else { - SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null"); - } + stt_client_s* client = stt_client_get_by_uid(uid); + if (NULL == client) { + SLOG(LOG_ERROR, TAG_STTC, "Handle not found"); + return -1; + } - if (STT_ERROR_SERVICE_RESET == reason) { - SLOG(LOG_WARN, TAG_STTC, "[WARNING] Service reset"); + client->reason = reason; + client->internal_state = STT_INTERNAL_STATE_NONE; + if (NULL != client->err_msg) { + free(client->err_msg); + client->err_msg = NULL; + } + if (NULL != err_msg) + client->err_msg = strdup(err_msg); + + SLOG(LOG_INFO, TAG_STTC, "internal state is initialized to 0"); + + if (NULL != client->error_cb) { + ecore_timer_add(0, __stt_notify_error, client); + } else { + SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null"); + } - client->current_state = STT_STATE_CREATED; - if (0 != stt_prepare(client->stt)) { - SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare"); + if (STT_ERROR_SERVICE_RESET == reason) { + SLOG(LOG_WARN, TAG_STTC, "[WARNING] Service reset"); + + client->current_state = STT_STATE_CREATED; + if (0 != stt_prepare(client->stt)) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare"); + } } } diff --git a/client/stt_dbus.c b/client/stt_dbus.c index 5f3a6a8..fe1dc72 100644 --- a/client/stt_dbus.c +++ b/client/stt_dbus.c @@ -615,6 +615,13 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle SLOG(LOG_DEBUG, TAG_STTC, " "); } /* STTD_METHOD_SPEECH_STATUS */ + else if (dbus_message_is_signal(msg, "org.freedesktop.DBus", "NameOwnerChanged")) { + SLOG(LOG_DEBUG, TAG_STTC, "===== Owner Changed"); + __stt_cb_error(-1, STT_ERROR_SERVICE_RESET, "Daemon Reset"); + SLOG(LOG_DEBUG, TAG_STTC, "====="); + SLOG(LOG_DEBUG, TAG_STTC, " "); + } /* NameOwnerChanged */ + else { SLOG(LOG_DEBUG, TAG_STTC, "Message is NOT valid"); dbus_message_unref(msg); @@ -965,6 +972,18 @@ int stt_dbus_request_initialize(int uid, bool* silence_supported, bool* credenti if (0 == result) { SLOG(LOG_DEBUG, TAG_STTC, "<<<< stt initialize : result = %d, silence(%d), credential(%d)", result, *silence_supported, *credential_needed); + + /* add a rule for daemon error */ + char rule_err[256] = {0, }; + snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", STT_SERVER_SERVICE_INTERFACE); + dbus_bus_add_match(g_conn_listener, rule_err, &err); + dbus_connection_flush(g_conn_listener); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_STTC, "Match Error (%s)", err.message); + dbus_error_free(&err); + return STT_ERROR_OPERATION_FAILED; + } } else { SLOG(LOG_ERROR, TAG_STTC, "<<<< stt initialize : result = %d", result); } @@ -987,6 +1006,19 @@ int stt_dbus_request_finalize(int uid) { DBusMessage* msg; + DBusError err; + dbus_error_init(&err); + + /* remove a rule for daemon error */ + char rule_err[256] = {0, }; + snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", STT_SERVER_SERVICE_INTERFACE); + dbus_bus_remove_match(g_conn_listener, rule_err, &err); + dbus_connection_flush(g_conn_listener); + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_STTC, "Match Error (%s)", err.message); + dbus_error_free(&err); + } + SLOG(LOG_DEBUG, TAG_STTC, "[dbus_info] service name: %s, service object: %s, service interface: %s", g_server_service_name, g_server_service_object, g_server_service_interface); msg = dbus_message_new_method_call( @@ -1004,9 +1036,6 @@ int stt_dbus_request_finalize(int uid) dbus_message_append_args(msg, DBUS_TYPE_INT32, &uid, DBUS_TYPE_INVALID); - DBusError err; - dbus_error_init(&err); - DBusMessage* result_msg; int result = STT_ERROR_OPERATION_FAILED; diff --git a/server/sttd_server.c b/server/sttd_server.c index bbb6a52..ed69892 100755 --- a/server/sttd_server.c +++ b/server/sttd_server.c @@ -429,51 +429,10 @@ void __sttd_server_silence_changed_cb(bool value, void* user_data) /* * Daemon function */ - -static void __sig_handler(int signo) -{ - /* restore signal handler */ - signal(signo, SIG_DFL); - - /* Send error signal to clients */ - int* client_list = NULL; - int client_count = 0; - int i = 0; - if (0 != sttd_client_get_list(&client_list, &client_count)) { - if (NULL != client_list) { - free(client_list); - client_list = NULL; - } - } - - if (NULL != client_list) { - for (i = 0; i < client_count; i++) { - sttdc_send_error_signal(client_list[i], STTD_ERROR_SERVICE_RESET, "Service Reset"); - } - - free(client_list); - client_list = NULL; - } - - /* invoke signal again */ - raise(signo); -} - -static void __register_sig_handler() -{ - signal(SIGSEGV, __sig_handler); - signal(SIGABRT, __sig_handler); - signal(SIGTERM, __sig_handler); - signal(SIGINT, __sig_handler); - signal(SIGQUIT, __sig_handler); -} - int sttd_initialize(stte_request_callback_s *callback) { int ret = 0; - __register_sig_handler(); - if (0 != pthread_mutex_init(&stte_result_mutex, NULL)) { SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize stte result mutex."); } -- 2.7.4 From fc8301e6d04bc4a807400e5a01f7dd87ad7461e7 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Mon, 26 Dec 2016 11:11:17 +0900 Subject: [PATCH 07/16] Add to cancel engine when error-result callback is invoked Change-Id: Ic1d9e4fdfa41e7186a0c6ff6099c004883e552fb Signed-off-by: sooyeon.kim (cherry picked from commit ca2ebf94e8879bb4328d6a5d307a0c6d390a30dc) --- server/sttd_server.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/server/sttd_server.c b/server/sttd_server.c index ed69892..037b4bf 100755 --- a/server/sttd_server.c +++ b/server/sttd_server.c @@ -87,12 +87,21 @@ static void __cancel_recognition_internal() g_recording_timer = NULL; } + int ret = 0; int uid = 0; uid = stt_client_get_current_recognition(); - if (0 != uid) { + app_state_e state = 0; + ret = sttd_client_get_state(uid, &state); + + if (0 != ret) { + SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid "); + return; + } + + if (0 != uid && (APP_STATE_PROCESSING == state || APP_STATE_RECORDING == state)) { /* cancel engine recognition */ - int ret = sttd_engine_agent_recognize_cancel(); + ret = sttd_engine_agent_recognize_cancel(); if (0 != ret) { SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret); } @@ -269,6 +278,14 @@ int __server_recognition_result_callback(stte_result_event_e event, const char* } sttd_config_time_reset(); + int ret = 0; + if (APP_STATE_RECORDING == state) { + ret = sttd_engine_agent_recognize_cancel(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel: result(%d)", ret); + } + } + sttd_client_set_state(uid, APP_STATE_READY); stt_client_unset_current_recognition(); -- 2.7.4 From e3e202d463f94aa58337a5e882f0772be9840bed Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Thu, 29 Dec 2016 18:47:17 +0900 Subject: [PATCH 08/16] Fix cancel by error Change-Id: I70d1b6530d1e1fa3fdf313e946d6336ad728157b Signed-off-by: sooyeon.kim (cherry picked from commit b1ef66f1491a3a429a035306606db1685d0f9654) --- server/sttd_server.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/server/sttd_server.c b/server/sttd_server.c index 037b4bf..8b91e60 100755 --- a/server/sttd_server.c +++ b/server/sttd_server.c @@ -101,19 +101,10 @@ static void __cancel_recognition_internal() if (0 != uid && (APP_STATE_PROCESSING == state || APP_STATE_RECORDING == state)) { /* cancel engine recognition */ - ret = sttd_engine_agent_recognize_cancel(); + ret = sttd_server_cancel(uid); if (0 != ret) { SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret); } - - /* change uid state */ - sttd_client_set_state(uid, APP_STATE_READY); - stt_client_unset_current_recognition(); - - ret = sttdc_send_set_state(uid, (int)APP_STATE_READY); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state change : result(%d)", ret); - } } else { SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid is NOT valid"); } -- 2.7.4 From 10f7b666cebe91587c946d7385612437c41f2cf6 Mon Sep 17 00:00:00 2001 From: Kwangyoun Kim Date: Wed, 28 Dec 2016 23:06:18 +0900 Subject: [PATCH 09/16] Update engine parser Change-Id: I6faf5e415c181d0c7f66875664206eed0ead870f Signed-off-by: Kwangyoun Kim (cherry picked from commit aff0743b37c29e520bfc6b5884b1cd71091cd9f4) --- engine-parser/src/stt-engine-parser.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) mode change 100755 => 100644 engine-parser/src/stt-engine-parser.c diff --git a/engine-parser/src/stt-engine-parser.c b/engine-parser/src/stt-engine-parser.c old mode 100755 new mode 100644 index a7d297d..06144b9 --- a/engine-parser/src/stt-engine-parser.c +++ b/engine-parser/src/stt-engine-parser.c @@ -54,6 +54,8 @@ #define STT_METADATA_LANGUAGE "http://tizen.org/metadata/stt-engine/language" #define STT_METADATA_SILENCE_DETECTION "http://tizen.org/metadata/stt-engine/silence-detection" #define STT_METADATA_CREDENTIAL_REQUIRED "http://tizen.org/metadata/stt-engine/credential-required" +#define STT_METADATA_ENGINE_SETTING "http://tizen.org/metadata/stt-engine/setting" +#define STT_METADATA_ENGINE_NAME "http://tizen.org/metadata/stt-engine/name" typedef struct metadata { const char *key; @@ -207,11 +209,6 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * } xmlDocSetRootElement(g_doc, root); - /* Save name */ - cur = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_NAME); - xmlNodeSetContent(cur, (const xmlChar*)pkgid); - xmlAddChild(root, cur); - iter = g_list_first(list); while (NULL != iter) { md = (metadata *)iter->data; @@ -227,6 +224,14 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * cur = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_CREDENTIAL); xmlNodeSetContent(cur, (const xmlChar*)md->value); xmlAddChild(root, cur); + } else if (!strcmp(md->key, STT_METADATA_ENGINE_SETTING)) { + cur = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_SETTING); + xmlNodeSetContent(cur, (const xmlChar*)md->value); + xmlAddChild(root, cur); + } else if (!strcmp(md->key, STT_METADATA_ENGINE_NAME)) { + cur = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_NAME); + xmlNodeSetContent(cur, (const xmlChar*)md->value); + xmlAddChild(root, cur); } else { LOGW("[WARNING] Unknown metadata type"); } -- 2.7.4 From c5e07da4116f1e98593b4e0f078dc58a591b6a94 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Thu, 29 Dec 2016 21:49:12 +0900 Subject: [PATCH 10/16] Fix dbus close connection and Add dangling pointer checker Change-Id: I14febbe09f983b93f02ebf06dac10686cc49e541 Signed-off-by: sooyeon.kim (cherry picked from commit 3e95b38a21ed23c279d5cec2f191736b67ac3ebb) --- server/sttd_dbus.c | 61 +++++++++++++++++++++++++++++++++++++++------------- server/sttd_server.c | 1 + 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/server/sttd_dbus.c b/server/sttd_dbus.c index 1bfcc03..0f68473 100644 --- a/server/sttd_dbus.c +++ b/server/sttd_dbus.c @@ -26,6 +26,7 @@ static DBusConnection* g_conn_sender = NULL; static DBusConnection* g_conn_listener = NULL; +static DBusConnection* g_conn_custom = NULL; static Ecore_Fd_Handler* g_dbus_fd_handler = NULL; @@ -499,6 +500,25 @@ void __sttd_dbus_service_free() } } +void __sttd_dbus_connection_free() +{ + if (NULL != g_conn_listener) { + dbus_connection_close(g_conn_listener); + dbus_connection_unref(g_conn_listener); + g_conn_listener = NULL; + } + if (NULL != g_conn_sender) { + dbus_connection_close(g_conn_sender); + dbus_connection_unref(g_conn_sender); + g_conn_sender = NULL; + } + if (NULL != g_conn_custom) { + dbus_connection_close(g_conn_custom); + dbus_connection_unref(g_conn_custom); + g_conn_custom = NULL; + } +} + int __sttd_get_buxtonkey() { /* request our name on the bus and check for errors */ @@ -588,6 +608,8 @@ int __sttd_get_buxtonkey() bux_cli = NULL; bux_layer = NULL; bux_val = NULL; + + __sttd_dbus_service_free(); return STTD_ERROR_OPERATION_FAILED; } @@ -615,7 +637,6 @@ int __sttd_get_buxtonkey() int __sttd_request_custom_dbus_name() { - static DBusConnection* g_conn_custom = NULL; DBusError err; dbus_error_init(&err); @@ -624,18 +645,21 @@ int __sttd_request_custom_dbus_name() if (dbus_error_is_set(&err)) { SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail dbus_bus_get : %s", err.message); dbus_error_free(&err); + __sttd_dbus_connection_free(); return STTD_ERROR_OPERATION_FAILED; } int ret = dbus_bus_request_name(g_conn_custom, STT_SERVER_CUSTOM_SERVICE_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING, &err); if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to be primary owner"); + __sttd_dbus_connection_free(); return STTD_ERROR_OPERATION_FAILED; } if (dbus_error_is_set(&err)) { SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_request_name() : %s", err.message); dbus_error_free(&err); + __sttd_dbus_connection_free(); return STTD_ERROR_OPERATION_FAILED; } @@ -643,6 +667,7 @@ int __sttd_request_custom_dbus_name() if (dbus_error_is_set(&err)) { SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_release_name() : %s", err.message); dbus_error_free(&err); + __sttd_dbus_connection_free(); return STTD_ERROR_OPERATION_FAILED; } @@ -683,6 +708,7 @@ int sttd_dbus_open_connection() if (NULL == g_conn_listener) { SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to get dbus connection"); + __sttd_dbus_connection_free(); return STTD_ERROR_OPERATION_FAILED; } @@ -690,12 +716,16 @@ int sttd_dbus_open_connection() ret = __sttd_get_buxtonkey(); if (0 != ret) { SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to get buxton key"); + __sttd_dbus_service_free(); + __sttd_dbus_connection_free(); return ret; } ret = __sttd_request_custom_dbus_name(); if (0 != ret) { SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to request custom dbus name"); + __sttd_dbus_service_free(); + __sttd_dbus_connection_free(); return ret; } @@ -703,12 +733,16 @@ int sttd_dbus_open_connection() if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to be primary owner"); + __sttd_dbus_service_free(); + __sttd_dbus_connection_free(); return STTD_ERROR_OPERATION_FAILED; } if (dbus_error_is_set(&err)) { SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_request_name() : %s", err.message); dbus_error_free(&err); + __sttd_dbus_service_free(); + __sttd_dbus_connection_free(); return STTD_ERROR_OPERATION_FAILED; } @@ -723,6 +757,8 @@ int sttd_dbus_open_connection() if (dbus_error_is_set(&err)) { SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_add_match() : %s", err.message); dbus_error_free(&err); + __sttd_dbus_service_free(); + __sttd_dbus_connection_free(); return STTD_ERROR_OPERATION_FAILED; } @@ -732,6 +768,8 @@ int sttd_dbus_open_connection() g_dbus_fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)listener_event_callback, g_conn_listener, NULL, NULL); if (NULL == g_dbus_fd_handler) { SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to get fd handler"); + __sttd_dbus_service_free(); + __sttd_dbus_connection_free(); return STTD_ERROR_OPERATION_FAILED; } @@ -748,22 +786,15 @@ int sttd_dbus_close_connection() g_dbus_fd_handler = NULL; } - dbus_bus_release_name(g_conn_listener, g_server_service_name, &err); - - if (dbus_error_is_set(&err)) { - SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_release_name() : %s", err.message); - dbus_error_free(&err); + if (NULL != g_conn_listener) { + dbus_bus_release_name(g_conn_listener, g_server_service_name, &err); + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_release_name() : %s", err.message); + dbus_error_free(&err); + } } - dbus_connection_close(g_conn_listener); - dbus_connection_close(g_conn_sender); - - dbus_connection_unref(g_conn_sender); - dbus_connection_unref(g_conn_listener); - - g_conn_listener = NULL; - g_conn_sender = NULL; - + __sttd_dbus_connection_free(); __sttd_dbus_service_free(); SLOG(LOG_DEBUG, TAG_STTD, "[Server] Close dbus connection"); diff --git a/server/sttd_server.c b/server/sttd_server.c index 8b91e60..a4f4e32 100755 --- a/server/sttd_server.c +++ b/server/sttd_server.c @@ -649,6 +649,7 @@ static Eina_Bool __quit_ecore_loop(void *data) stt_network_finalize(); sttd_finalize(); + sttd_dbus_close_connection(); ecore_main_loop_quit(); SLOG(LOG_DEBUG, TAG_STTD, ""); -- 2.7.4 From 3a75392dd280a6afbebf3e3939ded4b265e7c8fb Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Wed, 11 Jan 2017 14:58:04 +0900 Subject: [PATCH 11/16] Remove unnecessary logs and files Change-Id: I4ba63156838030fc4c153853763a6e6fac5d8146 Signed-off-by: sooyeon.kim (cherry picked from commit ea67c3ad26335d2ef99a76870b3cb247f4658361) --- CMakeLists.txt | 2 +- client/stt_dbus.c | 9 +++++---- packaging/stt.spec | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 767b057..c961bf1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,7 +63,7 @@ ADD_SUBDIRECTORY(client) ADD_SUBDIRECTORY(server) ## Test ## -ADD_SUBDIRECTORY(test) +#ADD_SUBDIRECTORY(test) ## Engine Parser ## ADD_SUBDIRECTORY(engine-parser) diff --git a/client/stt_dbus.c b/client/stt_dbus.c index fe1dc72..4406ac6 100644 --- a/client/stt_dbus.c +++ b/client/stt_dbus.c @@ -875,12 +875,12 @@ int stt_dbus_request_hello(int uid) } if (NULL == msg) { - SLOG(LOG_ERROR, TAG_STTC, ">>>> Request stt hello : Fail to make message"); - return STT_ERROR_OPERATION_FAILED; +// SLOG(LOG_ERROR, TAG_STTC, ">>>> Request stt hello : Fail to make message"); + result = stt_dbus_reconnect(); + if (0 != result) + return STT_ERROR_OPERATION_FAILED; } - - if (g_conn_sender) { result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, g_waiting_short_time, &err); dbus_message_unref(msg); @@ -907,6 +907,7 @@ int stt_dbus_request_hello(int uid) } } else { SLOG(LOG_WARN, TAG_STTC, "[WARN] dbus connection handle is null (%p)", g_conn_sender); + stt_dbus_reconnect(); result = STT_ERROR_OPERATION_FAILED; } diff --git a/packaging/stt.spec b/packaging/stt.spec index 358d33b..27bd80d 100644 --- a/packaging/stt.spec +++ b/packaging/stt.spec @@ -125,7 +125,7 @@ mkdir -p %{TZ_SYS_RO_SHARE}/voice/test %{TZ_SYS_RO_SHARE}/voice/stt/1.0/stt-config.xml %{TZ_SYS_RO_SHARE}/dbus-1/services/org.tizen.voice.sttserver.service %{TZ_SYS_RO_SHARE}/dbus-1/services/org.tizen.voice.sttservercustom.service -%{TZ_SYS_RO_SHARE}/voice/test/stt-test +#%{TZ_SYS_RO_SHARE}/voice/test/stt-test %{TZ_SYS_RO_SHARE}/license/%{name} #%{TZ_SYS_BIN}/* %{_bindir}/voice_getengine -- 2.7.4 From e5c5a41fb4080d3a9ea3bbb92ee0b91312378b4a Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Thu, 12 Jan 2017 13:32:37 +0900 Subject: [PATCH 12/16] Implement stt default engine setting and Fix directories in stt engine parser Change-Id: I3a159f0c143446dfc0d3dcc6ae5fcce4fa9062b4 Signed-off-by: sooyeon.kim --- CMakeLists.txt | 4 +- client/stt.c | 50 +++ common/stt_config_mgr.c | 6 +- engine-parser/src/stt-engine-parser.c | 785 +++++++++++++++++++++++++++++++--- packaging/stt.spec | 2 + server/sttd_server.c | 2 + 6 files changed, 786 insertions(+), 63 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c961bf1..96eabd3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,12 +40,12 @@ INCLUDE(FindPkgConfig) IF("${_TV_PRODUCT}" STREQUAL "TRUE") pkg_check_modules(pkgs REQUIRED aul capi-media-audio-io capi-media-wav-player capi-network-bluetooth capi-system-info cynara-client cynara-session - dbus-1 dlog ecore glib-2.0 libtzplatform-config libxml-2.0 vconf vconf-internal-keys buxton2 + dbus-1 dlog ecore glib-2.0 libgum libtzplatform-config libxml-2.0 libsystemd-login vconf vconf-internal-keys buxton2 ) ELSE() pkg_check_modules(pkgs REQUIRED aul capi-media-audio-io capi-media-wav-player capi-system-info cynara-client cynara-session - dbus-1 dlog ecore glib-2.0 libtzplatform-config libxml-2.0 vconf vconf-internal-keys buxton2 + dbus-1 dlog ecore glib-2.0 libgum libtzplatform-config libxml-2.0 libsystemd-login vconf vconf-internal-keys buxton2 ) ENDIF() diff --git a/client/stt.c b/client/stt.c index 780719e..149ac44 100644 --- a/client/stt.c +++ b/client/stt.c @@ -230,6 +230,33 @@ void __stt_config_lang_changed_cb(const char* before_language, const char* curre return; } +static Eina_Bool __reconnect_by_engine_changed(void *data) +{ + stt_h stt = (stt_h)data; + + stt_client_s* client = stt_client_get(stt); + if (NULL == client) { + SLOG(LOG_ERROR, TAG_STTC, "[WARNING] A handle is not valid"); + return EINA_FALSE; + } + + if (STT_STATE_READY != client->current_state) { + usleep(10000); + return EINA_TRUE; + } + + int ret = stt_unprepare(stt); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret); + } + ret = stt_prepare(stt); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret); + } + + return EINA_FALSE; +} + 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) { stt_h stt = (stt_h)user_data; @@ -245,6 +272,29 @@ void __stt_config_engine_changed_cb(const char* engine_id, const char* setting, if (NULL != language) SLOG(LOG_DEBUG, TAG_STTC, "Language(%s)", language); SLOG(LOG_DEBUG, TAG_STTC, "Silence(%s), Credential(%s)", support_silence ? "on" : "off", need_credential ? "need" : "no need"); + /* When the default engine is changed, please unload the old engine and load the new one. */ + int ret = -1; + + if (NULL == client->current_engine_id) { + if (STT_STATE_RECORDING == client->current_state || STT_STATE_PROCESSING == client->current_state) { + ret = stt_cancel(stt); + if (0 != ret) { + SLOG(LOG_DEBUG, TAG_STTC, "[DEBUG] STT client canceling..."); + } + + ecore_idler_add(__reconnect_by_engine_changed, (void*)stt); + } else if (STT_STATE_READY == client->current_state) { + ret = stt_unprepare(stt); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret); + } + ret = stt_prepare(stt); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare for setting a new engine... (%d)", ret); + } + } + } + /* call callback function */ if (NULL != client->engine_changed_cb) { client->engine_changed_cb(stt, engine_id, language, support_silence, need_credential, client->engine_changed_user_data); diff --git a/common/stt_config_mgr.c b/common/stt_config_mgr.c index b7cf83b..b2d346b 100755 --- a/common/stt_config_mgr.c +++ b/common/stt_config_mgr.c @@ -662,6 +662,8 @@ static void __get_engine_list(const char* directory) if (NULL == directory) { SLOG(LOG_ERROR, stt_tag(), "[Directory ERROR] Directory is NULL"); return; + } else { + SLOG(LOG_DEBUG, stt_tag(), "[Directory DEBUG] Directory: %s", directory); } dp = opendir(directory); @@ -677,7 +679,7 @@ static void __get_engine_list(const char* directory) char* filepath = NULL; int filesize; - filesize = strlen(STT_DEFAULT_ENGINE_INFO) + strlen(dirp->d_name) + 5; + filesize = strlen(directory) + strlen(dirp->d_name) + 5; filepath = (char*)calloc(filesize, sizeof(char)); if (NULL != filepath) { @@ -687,6 +689,8 @@ static void __get_engine_list(const char* directory) continue; } + SLOG(LOG_DEBUG, stt_tag(), "[File DEBUG] File path: %s", filepath); + if (0 == stt_parser_get_engine_info(filepath, &info)) { g_engine_list = g_slist_append(g_engine_list, info); } diff --git a/engine-parser/src/stt-engine-parser.c b/engine-parser/src/stt-engine-parser.c index 06144b9..ecf2ba0 100644 --- a/engine-parser/src/stt-engine-parser.c +++ b/engine-parser/src/stt-engine-parser.c @@ -26,6 +26,11 @@ #include #include #include +#include + +#include +#include +#include /* Define EXPORT_API */ #ifndef EXPORT_API @@ -49,7 +54,12 @@ #define STT_CONFIG_BASE tzplatform_mkpath(TZ_USER_HOME, "share/.voice") #define STT_HOME tzplatform_mkpath(TZ_USER_HOME, "share/.voice/stt") #define STT_ENGINE_BASE tzplatform_mkpath(TZ_USER_HOME, "share/.voice/stt/1.0") -#define STT_ENGINE_INFO tzplatform_mkpath(TZ_USER_HOME, "/share/.voice/stt/1.0/engine-info") +#define STT_ENGINE_INFO tzplatform_mkpath(TZ_USER_SHARE, ".voice/stt/1.0/engine-info") + +#define STT_GLOBAL_CONFIG_BASE "/etc/skel/share/.voice" +#define STT_GLOBAL_HOME "/etc/skel/share/.voice/stt" +#define STT_GLOBAL_ENGINE_BASE "/etc/skel/share/.voice/stt/1.0" +#define STT_GLOBAL_ENGINE_INFO "/etc/skel/share/.voice/stt/1.0/engine-info" #define STT_METADATA_LANGUAGE "http://tizen.org/metadata/stt-engine/language" #define STT_METADATA_SILENCE_DETECTION "http://tizen.org/metadata/stt-engine/silence-detection" @@ -63,6 +73,17 @@ typedef struct metadata { } metadata; static xmlDocPtr g_doc; +GumUser *g_guser = NULL; +uid_t g_uid = 301; // app_fw +gid_t g_gid = 301; // app_fw +GumUserType g_ut = GUM_USERTYPE_NONE; +gchar *g_user_type = NULL; + +char *g_dir_config_base = NULL; +char *g_dir_home = NULL; +char *g_dir_engine_base = NULL; +char *g_dir_engine_info = NULL; + static int __create_engine_info_xml(const char *pkgid) { @@ -76,66 +97,230 @@ static int __create_engine_info_xml(const char *pkgid) return 0; } -static int __save_engine_info_xml(const char *pkgid) +static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid, gid_t gid) { LOGD("=== Save engine info doc"); + char *dir_config_base = NULL; + char *dir_home = NULL; + char *dir_engine_base = NULL; + char *dir_engine_info = NULL; + + if (NULL == ut || (NULL != ut && 0 == strcmp(ut, "none"))) { + LOGE("[ERROR] Usertype is NONE"); + return -1; + } + + uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER); + uid_t tmp_uid = 0; + gid_t tmp_gid = 0; + LOGD("uid(%d)", uid); + + if (globalapp_uid == uid) { + /* Global app */ + dir_config_base = strdup(STT_GLOBAL_CONFIG_BASE); + dir_home = strdup(STT_GLOBAL_HOME); + dir_engine_base = strdup(STT_GLOBAL_ENGINE_BASE); + dir_engine_info = strdup(STT_GLOBAL_ENGINE_INFO); + tmp_uid = 301; // app_fw + tmp_gid = 301; // app_fw + } else { + /* User app, Guest app, Security app */ + if (NULL != g_dir_config_base) + dir_config_base = strdup(g_dir_config_base); + if (NULL != g_dir_home) + dir_home = strdup(g_dir_home); + if (NULL != g_dir_engine_base) + dir_engine_base = strdup(g_dir_engine_base); + if (NULL != g_dir_engine_info) + dir_engine_info = strdup(g_dir_engine_info); + tmp_uid = uid; + tmp_gid = gid; + } + + if (NULL == dir_config_base || NULL == dir_home || NULL == dir_engine_base || NULL == dir_engine_info) { + LOGE("[ERROR] Fail to allocate memory"); + if (NULL != dir_config_base) { + free(dir_config_base); + dir_config_base = NULL; + } + if (NULL != dir_home) { + free(dir_home); + dir_home = NULL; + } + if (NULL != dir_engine_base) { + free(dir_engine_base); + dir_engine_base = NULL; + } + if (NULL != dir_engine_info) { + free(dir_engine_info); + dir_engine_info = NULL; + } + return -1; + } + + LOGD("[DEBUG] dir_engine_info(%s)", dir_engine_info); + /* Make directories */ - if (0 != access(STT_CONFIG_BASE, F_OK)) { - if (0 != mkdir(STT_CONFIG_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { - LOGE("[ERROR] Fail to make directory : %s", STT_CONFIG_BASE); + if (0 != access(dir_config_base, F_OK)) { + if (0 != mkdir(dir_config_base, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + LOGE("[ERROR] Fail to make directory : %s", dir_config_base); + free(dir_config_base); + dir_config_base = NULL; + free(dir_home); + dir_home = NULL; + free(dir_engine_base); + dir_engine_base = NULL; + free(dir_engine_info); + dir_engine_info = NULL; return -1; } else { - LOGD("Success to make directory : %s", STT_CONFIG_BASE); + LOGD("Success to make directory : %s", dir_config_base); + if (0 != chown(dir_config_base, tmp_uid, tmp_gid)) { + LOGD("[ERROR] Fail to change user and group"); + } else { + LOGD("[DEBUG] Success to change user and group"); + } } } - if (0 != access(STT_HOME, F_OK)) { - if (0 != mkdir(STT_HOME, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { - LOGE("[ERROR] Fail to make directory : %s", STT_HOME); + if (0 != access(dir_home, F_OK)) { + if (0 != mkdir(dir_home, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + LOGE("[ERROR] Fail to make directory : %s", dir_home); + free(dir_config_base); + dir_config_base = NULL; + free(dir_home); + dir_home = NULL; + free(dir_engine_base); + dir_engine_base = NULL; + free(dir_engine_info); + dir_engine_info = NULL; return -1; } else { - LOGD("Success to make directory : %s", STT_HOME); + LOGD("Success to make directory : %s", dir_home); + if (0 != chown(dir_home, tmp_uid, tmp_gid)) { + LOGD("[ERROR] Fail to change user and group"); + } else { + LOGD("[DEBUG] Success to change user and group"); + } } } - if (0 != access(STT_ENGINE_BASE, F_OK)) { - if (0 != mkdir(STT_ENGINE_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { - LOGE("[ERROR] Fail to make directory : %s", STT_ENGINE_BASE); + if (0 != access(dir_engine_base, F_OK)) { + if (0 != mkdir(dir_engine_base, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + LOGE("[ERROR] Fail to make directory : %s", dir_engine_base); + free(dir_config_base); + dir_config_base = NULL; + free(dir_home); + dir_home = NULL; + free(dir_engine_base); + dir_engine_base = NULL; + free(dir_engine_info); + dir_engine_info = NULL; return -1; } else { - LOGD("Success to make directory : %s", STT_ENGINE_BASE); + LOGD("Success to make directory : %s", dir_engine_base); + if (0 != chown(dir_engine_base, tmp_uid, tmp_gid)) { + LOGD("[ERROR] Fail to change user and group"); + } else { + LOGD("[DEBUG] Success to change user and group"); + } } } - if (0 != access(STT_ENGINE_INFO, F_OK)) { - if (0 != mkdir(STT_ENGINE_INFO, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { - LOGE("[ERROR] Fail to make directory : %s", STT_ENGINE_INFO); + if (0 != access(dir_engine_info, F_OK)) { + if (0 != mkdir(dir_engine_info, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + LOGE("[ERROR] Fail to make directory : %s", dir_engine_info); + free(dir_config_base); + dir_config_base = NULL; + free(dir_home); + dir_home = NULL; + free(dir_engine_base); + dir_engine_base = NULL; + free(dir_engine_info); + dir_engine_info = NULL; return -1; } else { - LOGD("Success to make directory : %s", STT_ENGINE_INFO); + LOGD("Success to make directory : %s", dir_engine_info); + if (0 != chown(dir_engine_info, tmp_uid, tmp_gid)) { + LOGD("[ERROR] Fail to change user and group"); + } else { + LOGD("[DEBUG] Success to change user and group"); + } } } char path[256] = {'\0',}; - snprintf(path, 256, "%s/%s.xml", STT_ENGINE_INFO, pkgid); + snprintf(path, 256, "%s/%s.xml", dir_engine_info, pkgid); int ret = xmlSaveFormatFile(path, g_doc, 1); LOGD("xmlSaveFile (%d)", ret); + if (0 == ret) { + if (0 != chown(path, tmp_uid, tmp_gid)) { + LOGD("[ERROR] Fail to change user and group"); + } else { + LOGD("[DEBUG] Success to change user and group"); + } + } + + free(dir_config_base); + dir_config_base = NULL; + free(dir_home); + dir_home = NULL; + free(dir_engine_base); + dir_engine_base = NULL; + free(dir_engine_info); + dir_engine_info = NULL; + LOGD("==="); + return 0; } -static int __remove_engine_info_xml(const char *pkgid) +static int __remove_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid) { LOGD("=== Remove engine info doc"); + char *dir_engine_info = NULL; + + if (NULL == ut || (NULL != ut && 0 == strcmp(ut, "none"))) { + LOGE("[ERROR] Usertype is NONE"); + return -1; + } + + uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER); + + LOGD("uid(%d)", uid); + + if (globalapp_uid == uid) { + /* Global app */ + dir_engine_info = strdup(STT_GLOBAL_ENGINE_INFO); + } else { + /* User app, Guest app, Security app */ + if (NULL != g_dir_engine_info) + dir_engine_info = strdup(g_dir_engine_info); + } + + if (NULL == dir_engine_info) { + LOGE("[ERROR] Fail to allocate memory"); + return -1; + } + + LOGD("[DEBUG] dir_engine_info(%s)", dir_engine_info); + char path[256] = {'\0',}; - snprintf(path, 256, "%s/%s.xml", STT_ENGINE_INFO, pkgid); + snprintf(path, 256, "%s/%s.xml", dir_engine_info, pkgid); if (0 == access(path, F_OK)) { LOGD("Remove engine info xml(%s)", path); if (0 != remove(path)) { LOGE("[ERROR] Fail to emove engine info xml(%s)", path); } } + + if (NULL != dir_engine_info) { + free(dir_engine_info); + dir_engine_info = NULL; + } + LOGD("==="); + return 0; } @@ -164,35 +349,8 @@ static void __insert_language_from_metadata(xmlNodePtr root, const char *languag free(tmp_free); } -EXPORT_API -int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list) +static int __write_metadata_inxml(const char *pkgid, const char *appid, GList *list) { - LOGD("METADATA INSTALL"); - LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list)); - - uid_t uid = 0; - int ret = -1; - ret = pkgmgr_installer_info_get_target_uid(&uid); - if (ret < 0) { - LOGE("[ERROR] Fail to get target uid"); - return 0; - } else { - LOGD("uid(%d)", uid); - } - - ret = tzplatform_set_user(uid); - if (ret < 0) { - LOGE("[ERROR] Invalid uid"); - return 0; - } else { - LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/")); - } - - if (0 >= g_list_length(list)) { - LOGE("[ERROR] No Engine Metadata"); - return 0; - } - GList *iter = NULL; metadata *md = NULL; @@ -202,9 +360,10 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * xmlNodePtr cur = NULL; root = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_BASE); + if (NULL == root) { LOGE("[ERROR] Fail to get new node"); - xmlFreeDoc(g_doc); +// xmlFreeDoc(g_doc); return -1; } xmlDocSetRootElement(g_doc, root); @@ -244,13 +403,334 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * xmlAddChild(root, cur); LOGD(""); + return 0; +} + +EXPORT_API +int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list) +{ + LOGD("METADATA INSTALL"); + LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list)); + + int ret = -1; + ret = pkgmgr_installer_info_get_target_uid(&g_uid); + if (ret < 0) { + LOGE("[ERROR] Fail to get target uid"); + return 0; + } else { + LOGD("uid(%d)", g_uid); + printf("[Parser Debug][DEBUG] uid(%d)", g_uid); + } + + uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER); + if (globalapp_uid == g_uid) { + g_user_type = g_strdup("admin"); + } else { + g_guser = gum_user_get_sync(g_uid, FALSE); + if (NULL == g_guser) { + LOGE("[ERROR] g_guser is NULL"); + return -1; + } + + g_object_get(G_OBJECT(g_guser), "gid", &g_gid, NULL); + g_object_get(G_OBJECT(g_guser), "usertype", &g_ut, NULL); + g_user_type = g_strdup(gum_user_type_to_string(g_ut)); + } - if (0 != __save_engine_info_xml(pkgid)) { - LOGE("[ERROR] Fail to make engine info file"); + if (NULL == g_user_type) { + LOGE("[ERROR] Fail to allocate memory"); + if (NULL != g_guser) { + g_object_unref(g_guser); + g_guser = NULL; + } return -1; } + if (0 == strcmp(g_user_type, "none")) { + /* GUM_USERTYPE_NONE */ + LOGE("[ERROR] Fail to get target uid"); + g_object_unref(g_guser); + g_guser = NULL; + g_free(g_user_type); + return -1; + } + + if (globalapp_uid == g_uid) { + /* global directory */ + LOGD("[DEBUG] usertype: %s", g_user_type); + if (0 >= g_list_length(list)) { + LOGE("[ERROR] No Engine Metadata"); + g_free(g_user_type); + return 0; + } + + if (0 != __write_metadata_inxml(pkgid, appid, list)) { + LOGE("[ERROR] Fail to write metadata in the xml"); + xmlFreeDoc(g_doc); + g_free(g_user_type); + return -1; + } + + /* Save in /etc/skel/share/ */ + g_dir_config_base = strdup(STT_GLOBAL_CONFIG_BASE); + g_dir_home = strdup(STT_GLOBAL_HOME); + g_dir_engine_base = strdup(STT_GLOBAL_ENGINE_BASE); + g_dir_engine_info = strdup(STT_GLOBAL_ENGINE_INFO); + + if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) { + LOGE("[ERROR] Fail to allocate memory"); + if (NULL != g_dir_config_base) { + free(g_dir_config_base); + g_dir_config_base = NULL; + } + if (NULL != g_dir_home) { + free(g_dir_home); + g_dir_home = NULL; + } + if (NULL != g_dir_engine_base) { + free(g_dir_engine_base); + g_dir_engine_base = NULL; + } + if (NULL != g_dir_engine_info) { + free(g_dir_engine_info); + g_dir_engine_info = NULL; + } + xmlFreeDoc(g_doc); + g_free(g_user_type); + return -1; + } + + if (0 != __save_engine_info_xml(pkgid, g_user_type, g_uid, g_gid)) { + LOGE("[ERROR] Fail to make engine info file"); + xmlFreeDoc(g_doc); + g_free(g_user_type); + return -1; + } + + /* Get user data by using libgum */ + + GumUserService *gus = NULL; + GumUserList *users = NULL; + GumUserList *iter = NULL; + GumUser *user = NULL; + gchar **query; + GumUserType gumut = GUM_USERTYPE_NONE; + gchar *user_type = NULL; + + uid_t uid; + gid_t gid; + gchar *home_dir = NULL; + + gus = gum_user_service_create_sync(TRUE); + if (!gus) { + LOGE("Failed to create gum user service"); + g_free(g_user_type); + return -1; + } + + query = g_strsplit("admin,normal", ",", -1); + + users = gum_user_service_get_user_list_sync(gus, (const gchar *const *)query); + g_strfreev(query); + + if (!users) { + LOGE("Failed to get gum user list"); + g_object_unref(gus); + gus = NULL; + g_free(g_user_type); + return -1; + } + + /* Make new user list */ + + iter = users; + while (iter != NULL) { + user = (GumUser*) iter->data; + g_object_get(G_OBJECT(user), "uid", &uid, NULL); + if (NULL != home_dir) { + free(home_dir); + home_dir = NULL; + } + g_object_get(G_OBJECT(user), "gid", &gid, NULL); + g_object_get(G_OBJECT(user), "homedir", &home_dir, NULL); + g_object_get(G_OBJECT(user), "usertype", &gumut, NULL); + user_type = g_strdup(gum_user_type_to_string(gumut)); + if (NULL == user_type) { + gum_user_service_list_free(users); + g_object_unref(gus); + gus = NULL; + return -1; + } + + LOGD("[DEBUG] user info"); + if (NULL != home_dir) { + LOGD("[DEBUG] uid(%d), gid(%d), user_type(%s), home_dir(%s)", uid, gid, user_type, home_dir); + + g_dir_config_base = (char*)calloc(strlen(home_dir) + 14, sizeof(char)); + g_dir_home = (char*)calloc(strlen(home_dir) + 18, sizeof(char)); + g_dir_engine_base = (char*)calloc(strlen(home_dir) + 22, sizeof(char)); + g_dir_engine_info = (char*)calloc(strlen(home_dir) + 34, sizeof(char)); + + if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) { + LOGE("[ERROR] Fail to allocate memory"); + if (NULL != g_dir_config_base) { + free(g_dir_config_base); + g_dir_config_base = NULL; + } + if (NULL != g_dir_home) { + free(g_dir_home); + g_dir_home = NULL; + } + if (NULL != g_dir_engine_base) { + free(g_dir_engine_base); + g_dir_engine_base = NULL; + } + if (NULL != g_dir_engine_info) { + free(g_dir_engine_info); + g_dir_engine_info = NULL; + } + gum_user_service_list_free(users); + g_object_unref(gus); + gus = NULL; + return -1; + } + snprintf(g_dir_config_base, strlen(home_dir) + 14, "%s/share/.voice", home_dir); + snprintf(g_dir_home, strlen(home_dir) + 18, "%s/share/.voice/stt", home_dir); + snprintf(g_dir_engine_base, strlen(home_dir) + 22, "%s/share/.voice/stt/1.0", home_dir); + snprintf(g_dir_engine_info, strlen(home_dir) + 34, "%s/share/.voice/stt/1.0/engine-info", home_dir); + + LOGD("[DEBUG] g_dir_engine_info(%s)", g_dir_engine_info); + + if (0 != __save_engine_info_xml(pkgid, user_type, uid, gid)) { + LOGE("[ERROR] Fail to make engine info file"); + } + + free(g_dir_config_base); + g_dir_config_base = NULL; + free(g_dir_home); + g_dir_home = NULL; + free(g_dir_engine_base); + g_dir_engine_base = NULL; + free(g_dir_engine_info); + g_dir_engine_info = NULL; + + g_free(user_type); + user_type = NULL; + free(home_dir); + home_dir = NULL; + + iter = g_list_next(iter); + } else { + iter = g_list_next(iter); + } + + if (NULL != user_type) { + g_free(user_type); + user_type = NULL; + } + } + + gum_user_service_list_free(users); + g_object_unref(gus); + gus = NULL; + } else { + /* user directory */ + LOGD("[DEBUG] usertype: %s", g_user_type); + + ret = tzplatform_set_user(g_uid); + if (ret < 0) { + LOGE("[ERROR] Invalid uid"); + g_object_unref(g_guser); + g_guser = NULL; + g_free(g_user_type); + return 0; + } else { + LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/")); + printf("[Parser Debug][DEBUG] TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/")); + } + + if (0 >= g_list_length(list)) { + LOGE("[ERROR] No Engine Metadata"); + g_object_unref(g_guser); + g_guser = NULL; + g_free(g_user_type); + return 0; + } + + if (0 != __write_metadata_inxml(pkgid, appid, list)) { + LOGE("[ERROR] Fail to write metadata in the xml"); + xmlFreeDoc(g_doc); + g_object_unref(g_guser); + g_guser = NULL; + g_free(g_user_type); + return -1; + } + + g_dir_config_base = strdup(STT_CONFIG_BASE); + g_dir_home = strdup(STT_HOME); + g_dir_engine_base = strdup(STT_ENGINE_BASE); + g_dir_engine_info = strdup(STT_ENGINE_INFO); + + if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) { + LOGE("[ERROR] Fail to allocate memory"); + if (NULL != g_dir_config_base) { + free(g_dir_config_base); + g_dir_config_base = NULL; + } + if (NULL != g_dir_home) { + free(g_dir_home); + g_dir_home = NULL; + } + if (NULL != g_dir_engine_base) { + free(g_dir_engine_base); + g_dir_engine_base = NULL; + } + if (NULL != g_dir_engine_info) { + free(g_dir_engine_info); + g_dir_engine_info = NULL; + } + xmlFreeDoc(g_doc); + g_object_unref(g_guser); + g_guser = NULL; + g_free(g_user_type); + return -1; + } + + if (0 != __save_engine_info_xml(pkgid, g_user_type, g_uid, g_gid)) { + LOGE("[ERROR] Fail to make engine info file"); + xmlFreeDoc(g_doc); + if (NULL != g_guser) { + g_object_unref(g_guser); + g_guser = NULL; + } + g_free(g_user_type); + return -1; + } + } + xmlFreeDoc(g_doc); + if (NULL != g_guser) { + g_object_unref(g_guser); + g_guser = NULL; + } + g_free(g_user_type); + + if (NULL != g_dir_config_base) { + free(g_dir_config_base); + g_dir_config_base = NULL; + } + if (NULL != g_dir_home) { + free(g_dir_home); + g_dir_home = NULL; + } + if (NULL != g_dir_engine_base) { + free(g_dir_engine_base); + g_dir_engine_base = NULL; + } + if (NULL != g_dir_engine_info) { + free(g_dir_engine_info); + g_dir_engine_info = NULL; + } return 0; } @@ -261,17 +741,202 @@ int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList LOGD("METADATA UNINSTALL"); LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list)); - GList *iter = NULL; - metadata *md = NULL; + int ret = -1; + ret = pkgmgr_installer_info_get_target_uid(&g_uid); + if (ret < 0) { + LOGE("[ERROR] Fail to get target uid"); + return 0; + } else { + LOGD("uid(%d)", g_uid); + printf("[Parser Debug][DEBUG] uid(%d)", g_uid); + } + + uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER); + if (globalapp_uid == g_uid) { + g_user_type = g_strdup("admin"); + } else { + g_guser = gum_user_get_sync(g_uid, FALSE); + if (NULL == g_guser) { + LOGE("[ERROR] g_guser is NULL"); + return -1; + } + + g_object_get(G_OBJECT(g_guser), "usertype", &g_ut, NULL); + g_user_type = g_strdup(gum_user_type_to_string(g_ut)); + } + + if (NULL == g_user_type) { + LOGE("[ERROR] Fail to allocate memory"); + if (NULL != g_guser) { + g_object_unref(g_guser); + g_guser = NULL; + } + return -1; + } + + if (0 == strcmp(g_user_type, "none")) { + /* GUM_USERTYPE_NONE */ + LOGE("[ERROR] Fail to get target uid"); + g_object_unref(g_guser); + g_guser = NULL; + g_free(g_user_type); + return -1; + } + + if (globalapp_uid == g_uid) { + /* global directory */ + LOGD("[DEBUG] usertype: %s", g_user_type); + + /* Remove files in /etc/skel/share/ */ + g_dir_engine_info = strdup(STT_GLOBAL_ENGINE_INFO); + if (NULL == g_dir_engine_info) { + LOGE("[ERROR] Fail to allocate memory"); + g_free(g_user_type); + return -1; + } + + if (0 != __remove_engine_info_xml(pkgid, g_user_type, g_uid)) { + LOGE("[ERROR] Fail to remove engine info file"); + } + + /* Get user data by using libgum */ + + GumUserService *gus = NULL; + GumUserList *users = NULL; + GumUserList *iter = NULL; + GumUser *user = NULL; + gchar **query; + GumUserType gumut = GUM_USERTYPE_NONE; + gchar *user_type = NULL; + + uid_t uid; + gchar *home_dir = NULL; + + GList *md_iter = NULL; + metadata *md = NULL; + + gus = gum_user_service_create_sync(TRUE); + if (!gus) { + LOGE("Failed to create gum user service"); + g_free(g_user_type); + return -1; + } + + query = g_strsplit("admin,normal", ",", -1); + + users = gum_user_service_get_user_list_sync(gus, (const gchar *const *)query); + g_strfreev(query); + + if (!users) { + LOGE("Failed to get gum user list"); + g_object_unref(gus); + gus = NULL; + g_free(g_user_type); + return -1; + } + + /* Make new user list */ + + iter = users; + while (iter != NULL) { + user = (GumUser*) iter->data; + g_object_get(G_OBJECT(user), "uid", &uid, NULL); + if (NULL != home_dir) { + free(home_dir); + home_dir = NULL; + } + g_object_get(G_OBJECT(user), "homedir", &home_dir, NULL); + g_object_get(G_OBJECT(user), "usertype", &gumut, NULL); + user_type = g_strdup(gum_user_type_to_string(gumut)); + if (NULL == user_type) { + gum_user_service_list_free(users); + g_object_unref(gus); + gus = NULL; + return -1; + } + + if (NULL != home_dir) { + g_dir_engine_info = (char*)calloc(strlen(home_dir) + 34, sizeof(char)); + if (NULL == g_dir_engine_info) { + gum_user_service_list_free(users); + g_object_unref(gus); + gus = NULL; + return -1; + } + + snprintf(g_dir_engine_info, strlen(home_dir) + 34, "%s/share/.voice/stt/1.0/engine-info", home_dir); + + md_iter = g_list_first(list); + while (NULL != md_iter) { + md = (metadata *)md_iter->data; + LOGD(" - key(%s) value(%s)", md->key, md->value); + md_iter = g_list_next(md_iter); + } + + if (0 != __remove_engine_info_xml(pkgid, user_type, uid)) { + LOGE("[ERROR] Fail to remove engine info file"); + } + + free(home_dir); + home_dir = NULL; + + free(g_dir_engine_info); + g_dir_engine_info = NULL; + + g_free(user_type); + + LOGD("Finish release memory"); + iter = g_list_next(iter); + LOGD("Finish next iter"); + } else { + iter = g_list_next(iter); + } + } + + gum_user_service_list_free(users); + g_object_unref(gus); + gus = NULL; + } else { + /* user directory */ + LOGD("[DEBUG] usertype: %s", g_user_type); + + ret = tzplatform_set_user(g_uid); + if (ret < 0) { + LOGE("[ERROR] Invalid uid"); + g_object_unref(g_guser); + g_guser = NULL; + g_free(g_user_type); + return -1; + } else { + LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/")); + printf("[Parser Debug][DEBUG] TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/")); + } + + g_dir_engine_info = strdup(STT_ENGINE_INFO); + if (NULL == g_dir_engine_info) { + LOGE("[ERROR] Fail to allocate memory"); + g_object_unref(g_guser); + g_guser = NULL; + g_free(g_user_type); + return -1; + } + + if (0 != __remove_engine_info_xml(pkgid, g_user_type, g_uid)) { + LOGE("[ERROR] Fail to remove engine info file"); + } - iter = g_list_first(list); - while (NULL != iter) { - md = (metadata *)iter->data; - LOGD(" - key(%s) value(%s)", md->key, md->value); - iter = g_list_next(iter); } - __remove_engine_info_xml(pkgid); + if (NULL != g_guser) { + g_object_unref(g_guser); + g_guser = NULL; + } + g_free(g_user_type); + + if (NULL != g_dir_engine_info) { + free(g_dir_engine_info); + g_dir_engine_info = NULL; + } LOGD(""); return 0; diff --git a/packaging/stt.spec b/packaging/stt.spec index 27bd80d..23c9c3e 100644 --- a/packaging/stt.spec +++ b/packaging/stt.spec @@ -23,8 +23,10 @@ BuildRequires: pkgconfig(dbus-1) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(ecore) BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(libgum) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(libxml-2.0) +BuildRequires: pkgconfig(libsystemd) BuildRequires: pkgconfig(pkgmgr) BuildRequires: pkgconfig(pkgmgr-info) BuildRequires: pkgconfig(pkgmgr-installer) diff --git a/server/sttd_server.c b/server/sttd_server.c index a4f4e32..5b4e046 100755 --- a/server/sttd_server.c +++ b/server/sttd_server.c @@ -375,6 +375,7 @@ void __sttd_server_engine_changed_cb(const char* engine_id, const char* language SLOG(LOG_DEBUG, TAG_STTD, "[Server] New default engine : %s", engine_id); } +#if 0 /* need to change state of app to ready */ int uid; uid = stt_client_get_current_recognition(); @@ -402,6 +403,7 @@ void __sttd_server_engine_changed_cb(const char* engine_id, const char* language ret = sttd_engine_agent_set_silence_detection(support_silence); if (0 != ret) SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret); +#endif return; } -- 2.7.4 From 1fb781fe915be10e43d1c23b4c8c401b13d284a1 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Thu, 19 Jan 2017 17:35:39 +0900 Subject: [PATCH 13/16] Fix memory leak of ecore timer Change-Id: I4a884582b76c7fec294b6654a9456ebcc1652215 Signed-off-by: Suyeon Hwang (cherry picked from commit cd080b4f4e38f40d86ed7372348012bf0383bd88) --- server/sttd_server.c | 17 +++++++++++++++++ server/stte.c | 11 +---------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/server/sttd_server.c b/server/sttd_server.c index 5b4e046..f364cf3 100755 --- a/server/sttd_server.c +++ b/server/sttd_server.c @@ -24,6 +24,10 @@ #include "sttd_recorder.h" #include "sttd_server.h" + +#define CLIENT_CLEAN_UP_TIME 500 + + static pthread_mutex_t stte_result_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t stte_result_time_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -35,6 +39,7 @@ static double g_processing_timeout = 30; static double g_recording_timeout = 60; +static Ecore_Timer* g_check_client_timer = NULL; Ecore_Timer* g_recording_timer = NULL; Ecore_Timer* g_processing_timer = NULL; @@ -477,6 +482,11 @@ int sttd_initialize(stte_request_callback_s *callback) return ret; } + g_check_client_timer = ecore_timer_add(CLIENT_CLEAN_UP_TIME, sttd_cleanup_client, NULL); + if (NULL == g_check_client_timer) { + SLOG(LOG_WARN, TAG_STTD, "[Main Warning] Fail to create timer of client check"); + } + SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] initialize"); return 0; @@ -507,6 +517,13 @@ int sttd_finalize() sttd_engine_agent_release(); + if (NULL != g_check_client_timer) { + ecore_timer_del(g_check_client_timer); + g_check_client_timer = NULL; + + SLOG(LOG_INFO, TAG_STTD, "[INFO] Delete ecore timer handle"); + } + return STTD_ERROR_NONE; } diff --git a/server/stte.c b/server/stte.c index 89d4be0..2a00e12 100755 --- a/server/stte.c +++ b/server/stte.c @@ -22,10 +22,6 @@ #include "stte.h" -#define CLIENT_CLEAN_UP_TIME 500 - -static Ecore_Timer* g_check_client_timer = NULL; - int stte_main(int argc, char**argv, stte_request_callback_s *callback) { SLOG(LOG_DEBUG, TAG_STTD, "===== Start engine"); @@ -53,11 +49,6 @@ int stte_main(int argc, char**argv, stte_request_callback_s *callback) stt_network_initialize(); - g_check_client_timer = ecore_timer_add(CLIENT_CLEAN_UP_TIME, sttd_cleanup_client, NULL); - if (NULL == g_check_client_timer) { - SLOG(LOG_WARN, TAG_STTD, "[Main Warning] Fail to create timer of client check"); - } - SLOG(LOG_DEBUG, TAG_STTD, "[Main] stt-service start..."); SLOG(LOG_DEBUG, TAG_STTD, "====="); @@ -124,4 +115,4 @@ int stte_set_private_data_requested_cb(stte_private_data_requested_cb callback) SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send speech status"); } return ret; -} +} \ No newline at end of file -- 2.7.4 From 85692c071ad98f05bf8b4d4ec5c9683ba2af4f3e Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Wed, 18 Jan 2017 20:11:12 +0900 Subject: [PATCH 14/16] Fix restore logic Change-Id: Ib690ffbb7082ad0a66694de3b37faaff1a9d604f Signed-off-by: sooyeon.kim (cherry picked from commit ce77dafc7d0e9dad23d3009186b27b941d52f2fb) --- client/stt_dbus.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/client/stt_dbus.c b/client/stt_dbus.c index 4406ac6..f6ddbf0 100644 --- a/client/stt_dbus.c +++ b/client/stt_dbus.c @@ -617,6 +617,19 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle else if (dbus_message_is_signal(msg, "org.freedesktop.DBus", "NameOwnerChanged")) { SLOG(LOG_DEBUG, TAG_STTC, "===== Owner Changed"); + DBusError err; + dbus_error_init(&err); + + /* remove a rule for daemon error */ + char rule_err[256] = {0, }; + snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", g_server_service_interface); + dbus_bus_remove_match(g_conn_listener, rule_err, &err); + dbus_connection_flush(g_conn_listener); + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_STTC, "Match Error (%s)", err.message); + dbus_error_free(&err); + } + __stt_cb_error(-1, STT_ERROR_SERVICE_RESET, "Daemon Reset"); SLOG(LOG_DEBUG, TAG_STTC, "====="); SLOG(LOG_DEBUG, TAG_STTC, " "); @@ -976,7 +989,7 @@ int stt_dbus_request_initialize(int uid, bool* silence_supported, bool* credenti /* add a rule for daemon error */ char rule_err[256] = {0, }; - snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", STT_SERVER_SERVICE_INTERFACE); + snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", g_server_service_interface); dbus_bus_add_match(g_conn_listener, rule_err, &err); dbus_connection_flush(g_conn_listener); @@ -1012,7 +1025,7 @@ int stt_dbus_request_finalize(int uid) /* remove a rule for daemon error */ char rule_err[256] = {0, }; - snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", STT_SERVER_SERVICE_INTERFACE); + snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", g_server_service_interface); dbus_bus_remove_match(g_conn_listener, rule_err, &err); dbus_connection_flush(g_conn_listener); if (dbus_error_is_set(&err)) { -- 2.7.4 From f744e25a4a0ad43d1889ccf9216eddd5a1f148d2 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Fri, 20 Jan 2017 16:37:45 +0900 Subject: [PATCH 15/16] Fix engine parser to access directories Change-Id: I5d832f4a5715823aff37dc001d46c221a98f0e74 Signed-off-by: sooyeon.kim (cherry picked from commit 7182e71ccfbd807230f99c9a4fbe73cc49511da2) --- engine-parser/src/stt-engine-parser.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/engine-parser/src/stt-engine-parser.c b/engine-parser/src/stt-engine-parser.c index ecf2ba0..281818c 100644 --- a/engine-parser/src/stt-engine-parser.c +++ b/engine-parser/src/stt-engine-parser.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -161,9 +162,11 @@ static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid, gid_t LOGD("[DEBUG] dir_engine_info(%s)", dir_engine_info); /* Make directories */ - if (0 != access(dir_config_base, F_OK)) { +// if (0 != access(dir_config_base, F_OK)) { + if (-1 == open(dir_config_base, O_DIRECTORY)) { + LOGE("[INFO] No directory : %s, errno : %d", dir_config_base, errno); if (0 != mkdir(dir_config_base, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { - LOGE("[ERROR] Fail to make directory : %s", dir_config_base); + LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_config_base, errno); free(dir_config_base); dir_config_base = NULL; free(dir_home); @@ -176,16 +179,18 @@ static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid, gid_t } else { LOGD("Success to make directory : %s", dir_config_base); if (0 != chown(dir_config_base, tmp_uid, tmp_gid)) { - LOGD("[ERROR] Fail to change user and group"); + LOGD("[ERROR] Fail to change user and group, errno : %d", errno); } else { LOGD("[DEBUG] Success to change user and group"); } } } - if (0 != access(dir_home, F_OK)) { +// if (0 != access(dir_home, F_OK)) { + if (-1 == open(dir_home, O_DIRECTORY)) { + LOGE("[INFO] No directory : %s, errno : %d", dir_home, errno); if (0 != mkdir(dir_home, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { - LOGE("[ERROR] Fail to make directory : %s", dir_home); + LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_home, errno); free(dir_config_base); dir_config_base = NULL; free(dir_home); @@ -198,16 +203,18 @@ static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid, gid_t } else { LOGD("Success to make directory : %s", dir_home); if (0 != chown(dir_home, tmp_uid, tmp_gid)) { - LOGD("[ERROR] Fail to change user and group"); + LOGD("[ERROR] Fail to change user and group, errno : %d", errno); } else { LOGD("[DEBUG] Success to change user and group"); } } } - if (0 != access(dir_engine_base, F_OK)) { +// if (0 != access(dir_engine_base, F_OK)) { + if (-1 == open(dir_engine_base, O_DIRECTORY)) { + LOGE("[INFO] No directory : %s, errno : %d", dir_engine_base, errno); if (0 != mkdir(dir_engine_base, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { - LOGE("[ERROR] Fail to make directory : %s", dir_engine_base); + LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_engine_base, errno); free(dir_config_base); dir_config_base = NULL; free(dir_home); @@ -220,16 +227,18 @@ static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid, gid_t } else { LOGD("Success to make directory : %s", dir_engine_base); if (0 != chown(dir_engine_base, tmp_uid, tmp_gid)) { - LOGD("[ERROR] Fail to change user and group"); + LOGD("[ERROR] Fail to change user and group, errno : %d", errno); } else { LOGD("[DEBUG] Success to change user and group"); } } } - if (0 != access(dir_engine_info, F_OK)) { +// if (0 != access(dir_engine_info, F_OK)) { + if (-1 == open(dir_engine_info, O_DIRECTORY)) { + LOGE("[INFO] No directory : %s, errno : %d", dir_engine_info, errno); if (0 != mkdir(dir_engine_info, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { - LOGE("[ERROR] Fail to make directory : %s", dir_engine_info); + LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_engine_info, errno); free(dir_config_base); dir_config_base = NULL; free(dir_home); @@ -242,7 +251,7 @@ static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid, gid_t } else { LOGD("Success to make directory : %s", dir_engine_info); if (0 != chown(dir_engine_info, tmp_uid, tmp_gid)) { - LOGD("[ERROR] Fail to change user and group"); + LOGD("[ERROR] Fail to change user and group, errno : %d", errno); } else { LOGD("[DEBUG] Success to change user and group"); } -- 2.7.4 From a29da87bf79773a976e106cef1c7a8b57628ea21 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Thu, 16 Feb 2017 14:11:28 +0900 Subject: [PATCH 16/16] Fix memory leak / Define memory free macro Change-Id: I86a9dc04238f0cfd123be20785adf7be7ce8e96a Signed-off-by: Suyeon Hwang (cherry picked from commit 3a6e7970b0a713fd707c1a620ed99d73945895d1) --- engine-parser/src/stt-engine-parser.c | 308 +++++++++++++--------------------- 1 file changed, 113 insertions(+), 195 deletions(-) diff --git a/engine-parser/src/stt-engine-parser.c b/engine-parser/src/stt-engine-parser.c index 281818c..8c4b201 100644 --- a/engine-parser/src/stt-engine-parser.c +++ b/engine-parser/src/stt-engine-parser.c @@ -68,6 +68,10 @@ #define STT_METADATA_ENGINE_SETTING "http://tizen.org/metadata/stt-engine/setting" #define STT_METADATA_ENGINE_NAME "http://tizen.org/metadata/stt-engine/name" +/* Define Macro */ +#define FREE(x) { if (NULL != x) { free(x); x = NULL; } } +#define G_FREE(x) { if (NULL != x) { g_free(x); x = NULL; } } + typedef struct metadata { const char *key; const char *value; @@ -140,41 +144,27 @@ static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid, gid_t if (NULL == dir_config_base || NULL == dir_home || NULL == dir_engine_base || NULL == dir_engine_info) { LOGE("[ERROR] Fail to allocate memory"); - if (NULL != dir_config_base) { - free(dir_config_base); - dir_config_base = NULL; - } - if (NULL != dir_home) { - free(dir_home); - dir_home = NULL; - } - if (NULL != dir_engine_base) { - free(dir_engine_base); - dir_engine_base = NULL; - } - if (NULL != dir_engine_info) { - free(dir_engine_info); - dir_engine_info = NULL; - } + FREE(dir_config_base) + FREE(dir_home) + FREE(dir_engine_base) + FREE(dir_engine_info) return -1; } LOGD("[DEBUG] dir_engine_info(%s)", dir_engine_info); /* Make directories */ + int fd = -1; // if (0 != access(dir_config_base, F_OK)) { - if (-1 == open(dir_config_base, O_DIRECTORY)) { + fd = open(dir_config_base, O_DIRECTORY); + if (-1 == fd) { LOGE("[INFO] No directory : %s, errno : %d", dir_config_base, errno); if (0 != mkdir(dir_config_base, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_config_base, errno); - free(dir_config_base); - dir_config_base = NULL; - free(dir_home); - dir_home = NULL; - free(dir_engine_base); - dir_engine_base = NULL; - free(dir_engine_info); - dir_engine_info = NULL; + FREE(dir_config_base) + FREE(dir_home) + FREE(dir_engine_base) + FREE(dir_engine_info) return -1; } else { LOGD("Success to make directory : %s", dir_config_base); @@ -184,21 +174,20 @@ static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid, gid_t LOGD("[DEBUG] Success to change user and group"); } } + } else { + close(fd); } // if (0 != access(dir_home, F_OK)) { - if (-1 == open(dir_home, O_DIRECTORY)) { + fd = open(dir_home, O_DIRECTORY); + if (-1 == fd) { LOGE("[INFO] No directory : %s, errno : %d", dir_home, errno); if (0 != mkdir(dir_home, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_home, errno); - free(dir_config_base); - dir_config_base = NULL; - free(dir_home); - dir_home = NULL; - free(dir_engine_base); - dir_engine_base = NULL; - free(dir_engine_info); - dir_engine_info = NULL; + FREE(dir_config_base) + FREE(dir_home) + FREE(dir_engine_base) + FREE(dir_engine_info) return -1; } else { LOGD("Success to make directory : %s", dir_home); @@ -208,21 +197,20 @@ static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid, gid_t LOGD("[DEBUG] Success to change user and group"); } } + } else { + close(fd); } // if (0 != access(dir_engine_base, F_OK)) { - if (-1 == open(dir_engine_base, O_DIRECTORY)) { + fd = open(dir_engine_base, O_DIRECTORY); + if (-1 == fd) { LOGE("[INFO] No directory : %s, errno : %d", dir_engine_base, errno); if (0 != mkdir(dir_engine_base, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_engine_base, errno); - free(dir_config_base); - dir_config_base = NULL; - free(dir_home); - dir_home = NULL; - free(dir_engine_base); - dir_engine_base = NULL; - free(dir_engine_info); - dir_engine_info = NULL; + FREE(dir_config_base) + FREE(dir_home) + FREE(dir_engine_base) + FREE(dir_engine_info) return -1; } else { LOGD("Success to make directory : %s", dir_engine_base); @@ -232,21 +220,20 @@ static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid, gid_t LOGD("[DEBUG] Success to change user and group"); } } + } else { + close(fd); } // if (0 != access(dir_engine_info, F_OK)) { - if (-1 == open(dir_engine_info, O_DIRECTORY)) { + fd = open(dir_engine_info, O_DIRECTORY); + if (-1 == fd) { LOGE("[INFO] No directory : %s, errno : %d", dir_engine_info, errno); if (0 != mkdir(dir_engine_info, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_engine_info, errno); - free(dir_config_base); - dir_config_base = NULL; - free(dir_home); - dir_home = NULL; - free(dir_engine_base); - dir_engine_base = NULL; - free(dir_engine_info); - dir_engine_info = NULL; + FREE(dir_config_base) + FREE(dir_home) + FREE(dir_engine_base) + FREE(dir_engine_info) return -1; } else { LOGD("Success to make directory : %s", dir_engine_info); @@ -256,6 +243,8 @@ static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid, gid_t LOGD("[DEBUG] Success to change user and group"); } } + } else { + close(fd); } char path[256] = {'\0',}; @@ -270,14 +259,10 @@ static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid, gid_t } } - free(dir_config_base); - dir_config_base = NULL; - free(dir_home); - dir_home = NULL; - free(dir_engine_base); - dir_engine_base = NULL; - free(dir_engine_info); - dir_engine_info = NULL; + FREE(dir_config_base) + FREE(dir_home) + FREE(dir_engine_base) + FREE(dir_engine_info) LOGD("==="); @@ -323,10 +308,7 @@ static int __remove_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid) } } - if (NULL != dir_engine_info) { - free(dir_engine_info); - dir_engine_info = NULL; - } + FREE(dir_engine_info) LOGD("==="); @@ -338,6 +320,11 @@ static void __insert_language_from_metadata(xmlNodePtr root, const char *languag LOGD("==== Insert language"); char* lang = NULL; + if (NULL == root || NULL == language) { + LOGE("Invalid parameter, root(%p), language(%s)", root, language); + return; + } + char *tmp_lang, *tmp_free; tmp_free = tmp_lang = strdup(language); xmlNodePtr languages_node = NULL; @@ -355,7 +342,7 @@ static void __insert_language_from_metadata(xmlNodePtr root, const char *languag } xmlAddChild(root, languages_node); - free(tmp_free); + FREE(tmp_free) } static int __write_metadata_inxml(const char *pkgid, const char *appid, GList *list) @@ -460,7 +447,7 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * LOGE("[ERROR] Fail to get target uid"); g_object_unref(g_guser); g_guser = NULL; - g_free(g_user_type); + G_FREE(g_user_type) return -1; } @@ -469,14 +456,14 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * LOGD("[DEBUG] usertype: %s", g_user_type); if (0 >= g_list_length(list)) { LOGE("[ERROR] No Engine Metadata"); - g_free(g_user_type); + G_FREE(g_user_type) return 0; } if (0 != __write_metadata_inxml(pkgid, appid, list)) { LOGE("[ERROR] Fail to write metadata in the xml"); xmlFreeDoc(g_doc); - g_free(g_user_type); + G_FREE(g_user_type) return -1; } @@ -488,31 +475,19 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) { LOGE("[ERROR] Fail to allocate memory"); - if (NULL != g_dir_config_base) { - free(g_dir_config_base); - g_dir_config_base = NULL; - } - if (NULL != g_dir_home) { - free(g_dir_home); - g_dir_home = NULL; - } - if (NULL != g_dir_engine_base) { - free(g_dir_engine_base); - g_dir_engine_base = NULL; - } - if (NULL != g_dir_engine_info) { - free(g_dir_engine_info); - g_dir_engine_info = NULL; - } + FREE(g_dir_config_base) + FREE(g_dir_home) + FREE(g_dir_engine_base) + FREE(g_dir_engine_info) xmlFreeDoc(g_doc); - g_free(g_user_type); + G_FREE(g_user_type) return -1; } if (0 != __save_engine_info_xml(pkgid, g_user_type, g_uid, g_gid)) { LOGE("[ERROR] Fail to make engine info file"); xmlFreeDoc(g_doc); - g_free(g_user_type); + G_FREE(g_user_type) return -1; } @@ -533,7 +508,7 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * gus = gum_user_service_create_sync(TRUE); if (!gus) { LOGE("Failed to create gum user service"); - g_free(g_user_type); + G_FREE(g_user_type) return -1; } @@ -546,7 +521,7 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * LOGE("Failed to get gum user list"); g_object_unref(gus); gus = NULL; - g_free(g_user_type); + G_FREE(g_user_type) return -1; } @@ -556,16 +531,15 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * while (iter != NULL) { user = (GumUser*) iter->data; g_object_get(G_OBJECT(user), "uid", &uid, NULL); - if (NULL != home_dir) { - free(home_dir); - home_dir = NULL; - } + G_FREE(home_dir) + g_object_get(G_OBJECT(user), "gid", &gid, NULL); g_object_get(G_OBJECT(user), "homedir", &home_dir, NULL); g_object_get(G_OBJECT(user), "usertype", &gumut, NULL); user_type = g_strdup(gum_user_type_to_string(gumut)); if (NULL == user_type) { gum_user_service_list_free(users); + G_FREE(home_dir) g_object_unref(gus); gus = NULL; return -1; @@ -582,25 +556,15 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) { LOGE("[ERROR] Fail to allocate memory"); - if (NULL != g_dir_config_base) { - free(g_dir_config_base); - g_dir_config_base = NULL; - } - if (NULL != g_dir_home) { - free(g_dir_home); - g_dir_home = NULL; - } - if (NULL != g_dir_engine_base) { - free(g_dir_engine_base); - g_dir_engine_base = NULL; - } - if (NULL != g_dir_engine_info) { - free(g_dir_engine_info); - g_dir_engine_info = NULL; - } + FREE(g_dir_config_base) + FREE(g_dir_home) + FREE(g_dir_engine_base) + FREE(g_dir_engine_info) gum_user_service_list_free(users); g_object_unref(gus); gus = NULL; + G_FREE(user_type) + G_FREE(home_dir) return -1; } snprintf(g_dir_config_base, strlen(home_dir) + 14, "%s/share/.voice", home_dir); @@ -614,29 +578,16 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * LOGE("[ERROR] Fail to make engine info file"); } - free(g_dir_config_base); - g_dir_config_base = NULL; - free(g_dir_home); - g_dir_home = NULL; - free(g_dir_engine_base); - g_dir_engine_base = NULL; - free(g_dir_engine_info); - g_dir_engine_info = NULL; - - g_free(user_type); - user_type = NULL; - free(home_dir); - home_dir = NULL; - - iter = g_list_next(iter); - } else { - iter = g_list_next(iter); - } + FREE(g_dir_config_base) + FREE(g_dir_home) + FREE(g_dir_engine_base) + FREE(g_dir_engine_info) - if (NULL != user_type) { - g_free(user_type); - user_type = NULL; + G_FREE(home_dir) } + + G_FREE(user_type) + iter = g_list_next(iter); } gum_user_service_list_free(users); @@ -651,7 +602,7 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * LOGE("[ERROR] Invalid uid"); g_object_unref(g_guser); g_guser = NULL; - g_free(g_user_type); + G_FREE(g_user_type) return 0; } else { LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/")); @@ -662,7 +613,7 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * LOGE("[ERROR] No Engine Metadata"); g_object_unref(g_guser); g_guser = NULL; - g_free(g_user_type); + G_FREE(g_user_type) return 0; } @@ -671,7 +622,7 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * xmlFreeDoc(g_doc); g_object_unref(g_guser); g_guser = NULL; - g_free(g_user_type); + G_FREE(g_user_type) return -1; } @@ -682,26 +633,14 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) { LOGE("[ERROR] Fail to allocate memory"); - if (NULL != g_dir_config_base) { - free(g_dir_config_base); - g_dir_config_base = NULL; - } - if (NULL != g_dir_home) { - free(g_dir_home); - g_dir_home = NULL; - } - if (NULL != g_dir_engine_base) { - free(g_dir_engine_base); - g_dir_engine_base = NULL; - } - if (NULL != g_dir_engine_info) { - free(g_dir_engine_info); - g_dir_engine_info = NULL; - } + FREE(g_dir_config_base) + FREE(g_dir_home) + FREE(g_dir_engine_base) + FREE(g_dir_engine_info) xmlFreeDoc(g_doc); g_object_unref(g_guser); g_guser = NULL; - g_free(g_user_type); + G_FREE(g_user_type) return -1; } @@ -712,7 +651,7 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * g_object_unref(g_guser); g_guser = NULL; } - g_free(g_user_type); + G_FREE(g_user_type) return -1; } } @@ -722,24 +661,12 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * g_object_unref(g_guser); g_guser = NULL; } - g_free(g_user_type); + G_FREE(g_user_type) - if (NULL != g_dir_config_base) { - free(g_dir_config_base); - g_dir_config_base = NULL; - } - if (NULL != g_dir_home) { - free(g_dir_home); - g_dir_home = NULL; - } - if (NULL != g_dir_engine_base) { - free(g_dir_engine_base); - g_dir_engine_base = NULL; - } - if (NULL != g_dir_engine_info) { - free(g_dir_engine_info); - g_dir_engine_info = NULL; - } + FREE(g_dir_config_base) + FREE(g_dir_home) + FREE(g_dir_engine_base) + FREE(g_dir_engine_info) return 0; } @@ -788,7 +715,7 @@ int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList LOGE("[ERROR] Fail to get target uid"); g_object_unref(g_guser); g_guser = NULL; - g_free(g_user_type); + G_FREE(g_user_type) return -1; } @@ -800,7 +727,7 @@ int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList g_dir_engine_info = strdup(STT_GLOBAL_ENGINE_INFO); if (NULL == g_dir_engine_info) { LOGE("[ERROR] Fail to allocate memory"); - g_free(g_user_type); + G_FREE(g_user_type) return -1; } @@ -827,7 +754,7 @@ int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList gus = gum_user_service_create_sync(TRUE); if (!gus) { LOGE("Failed to create gum user service"); - g_free(g_user_type); + G_FREE(g_user_type) return -1; } @@ -840,7 +767,7 @@ int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList LOGE("Failed to get gum user list"); g_object_unref(gus); gus = NULL; - g_free(g_user_type); + G_FREE(g_user_type) return -1; } @@ -850,15 +777,13 @@ int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList while (iter != NULL) { user = (GumUser*) iter->data; g_object_get(G_OBJECT(user), "uid", &uid, NULL); - if (NULL != home_dir) { - free(home_dir); - home_dir = NULL; - } + G_FREE(home_dir) g_object_get(G_OBJECT(user), "homedir", &home_dir, NULL); g_object_get(G_OBJECT(user), "usertype", &gumut, NULL); user_type = g_strdup(gum_user_type_to_string(gumut)); if (NULL == user_type) { gum_user_service_list_free(users); + G_FREE(home_dir) g_object_unref(gus); gus = NULL; return -1; @@ -868,8 +793,10 @@ int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList g_dir_engine_info = (char*)calloc(strlen(home_dir) + 34, sizeof(char)); if (NULL == g_dir_engine_info) { gum_user_service_list_free(users); + G_FREE(home_dir) g_object_unref(gus); gus = NULL; + G_FREE(user_type) return -1; } @@ -886,20 +813,14 @@ int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList LOGE("[ERROR] Fail to remove engine info file"); } - free(home_dir); - home_dir = NULL; - - free(g_dir_engine_info); - g_dir_engine_info = NULL; - - g_free(user_type); - - LOGD("Finish release memory"); - iter = g_list_next(iter); - LOGD("Finish next iter"); - } else { - iter = g_list_next(iter); + G_FREE(home_dir) + G_FREE(g_dir_engine_info) } + G_FREE(user_type) + + LOGD("Finish release memory"); + iter = g_list_next(iter); + LOGD("Finish next iter"); } gum_user_service_list_free(users); @@ -914,7 +835,7 @@ int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList LOGE("[ERROR] Invalid uid"); g_object_unref(g_guser); g_guser = NULL; - g_free(g_user_type); + G_FREE(g_user_type) return -1; } else { LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/")); @@ -926,7 +847,7 @@ int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList LOGE("[ERROR] Fail to allocate memory"); g_object_unref(g_guser); g_guser = NULL; - g_free(g_user_type); + G_FREE(g_user_type) return -1; } @@ -940,12 +861,9 @@ int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList g_object_unref(g_guser); g_guser = NULL; } - g_free(g_user_type); + G_FREE(g_user_type) - if (NULL != g_dir_engine_info) { - free(g_dir_engine_info); - g_dir_engine_info = NULL; - } + FREE(g_dir_engine_info) LOGD(""); return 0; -- 2.7.4