Implement stt default engine setting and Fix directories in stt engine parser 49/109849/1 accepted/tizen_common accepted/tizen_ivi accepted/tizen_mobile accepted/tizen_tv accepted/tizen_wearable accepted/tizen/common/20170117.174608 accepted/tizen/ivi/20170117.054244 accepted/tizen/mobile/20170117.054147 accepted/tizen/tv/20170117.054205 accepted/tizen/unified/20170309.034311 accepted/tizen/unified/20170406.054104 accepted/tizen/wearable/20170117.054226 submit/tizen/20170117.020319 submit/tizen/20170405.010045 submit/tizen_unified/20170308.100410
authorsooyeon.kim <sooyeon.kim@samsung.com>
Thu, 12 Jan 2017 04:32:37 +0000 (13:32 +0900)
committersooyeon.kim <sooyeon.kim@samsung.com>
Thu, 12 Jan 2017 04:33:17 +0000 (13:33 +0900)
Change-Id: I3a159f0c143446dfc0d3dcc6ae5fcce4fa9062b4
Signed-off-by: sooyeon.kim <sooyeon.kim@samsung.com>
CMakeLists.txt
client/stt.c
common/stt_config_mgr.c
engine-parser/src/stt-engine-parser.c
packaging/stt.spec
server/sttd_server.c

index c961bf1..96eabd3 100644 (file)
@@ -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()
 
index 780719e..149ac44 100644 (file)
@@ -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);
index b7cf83b..b2d346b 100755 (executable)
@@ -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);
                                }
index 06144b9..ecf2ba0 100644 (file)
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <tzplatform_config.h>
+#include <systemd/sd-login.h>
+
+#include <gum/gum-user.h>
+#include <gum/gum-user-service.h>
+#include <gum/common/gum-user-types.h>
 
 /* Define EXPORT_API */
 #ifndef EXPORT_API
 #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;
index 27bd80d..23c9c3e 100644 (file)
@@ -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)
index a4f4e32..5b4e046 100755 (executable)
@@ -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;
 }