From e5c5a41fb4080d3a9ea3bbb92ee0b91312378b4a Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Thu, 12 Jan 2017 13:32:37 +0900 Subject: [PATCH] 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