2 // Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
17 #include <app_manager.h>
21 #include <libxml/parser.h>
22 #include <libxml/tree.h>
23 #include <pkgmgr-info.h>
24 #include <pkgmgr_installer_info.h>
27 #include <sys/types.h>
29 #include <tzplatform_config.h>
30 #include <systemd/sd-login.h>
32 #include <gum/gum-user.h>
33 #include <gum/gum-user-service.h>
34 #include <gum/common/gum-user-types.h>
36 /* Define EXPORT_API */
38 #define EXPORT_API __attribute__((visibility("default")))
44 #define LOG_TAG "tts-engine-parser"
46 #define TTS_TAG_ENGINE_BASE "tts-engine"
47 #define TTS_TAG_ENGINE_NAME "name"
48 #define TTS_TAG_ENGINE_ID "id"
49 #define TTS_TAG_ENGINE_SETTING "setting"
50 #define TTS_TAG_ENGINE_VOICE_SET "voices"
51 #define TTS_TAG_ENGINE_VOICE "voice"
52 #define TTS_TAG_ENGINE_VOICE_TYPE "type"
53 #define TTS_TAG_ENGINE_PITCH_SUPPORT "pitch-support"
54 #define TTS_TAG_ENGINE_CREDENTIAL "credential"
55 #define TTS_TAG_ENGINE_TEXT_SIZE "text-size"
57 #define TTS_CONFIG_BASE tzplatform_mkpath(TZ_USER_HOME, "share/.voice")
58 #define TTS_HOME tzplatform_mkpath(TZ_USER_HOME, "share/.voice/tts")
59 #define TTS_ENGINE_BASE tzplatform_mkpath(TZ_USER_HOME, "share/.voice/tts/1.0")
60 #define TTS_ENGINE_INFO tzplatform_mkpath(TZ_USER_SHARE, ".voice/tts/1.0/engine-info")
62 #define TTS_GLOBAL_CONFIG_BASE "/etc/skel/share/.voice"
63 #define TTS_GLOBAL_HOME "/etc/skel/share/.voice/tts"
64 #define TTS_GLOBAL_ENGINE_BASE "/etc/skel/share/.voice/tts/1.0"
65 #define TTS_GLOBAL_ENGINE_INFO "/etc/skel/share/.voice/tts/1.0/engine-info"
67 #define TTS_METADATA_NAME "http://tizen.org/metadata/tts-engine/name"
68 #define TTS_METADATA_LANGUAGE "http://tizen.org/metadata/tts-engine/language"
69 #define TTS_METADATA_CREDENTIAL_REQUIRED "http://tizen.org/metadata/tts-engine/credential-required"
70 #define TTS_METADATA_SETTING "http://tizen.org/metadata/tts-engine/setting"
71 #define TTS_METADATA_TEXT_SIZE "http://tizen.org/metadata/tts-engine/text-size"
72 #define TTS_METADATA_PITCH_SUPPORT "http://tizen.org/metadata/tts-engine/pitch-support"
74 #define TTS_MAX_TEXT_SIZE "2000"
77 #define FREE(x) { if (NULL != x) { free(x); x = NULL; } }
78 #define G_FREE(x) { if (NULL != x) { g_free(x); x = NULL; } }
80 typedef struct metadata {
85 static xmlDocPtr g_doc;
86 GumUser *g_guser = NULL;
87 uid_t g_uid = 301; // app_fw
88 gid_t g_gid = 301; // app_fw
89 GumUserType g_ut = GUM_USERTYPE_NONE;
90 gchar *g_user_type = NULL;
92 char *g_dir_config_base = NULL;
93 char *g_dir_home = NULL;
94 char *g_dir_engine_base = NULL;
95 char *g_dir_engine_info = NULL;
98 static int __create_engine_info_xml(const char *pkgid)
100 LOGD("@@@ Create engine info doc");
101 g_doc = xmlNewDoc((xmlChar*)"1.0");
103 LOGE("[ERROR] Fail to new doc");
110 static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid, gid_t gid)
112 LOGD("@@@ Save engine info doc");
113 char *dir_config_base = NULL;
114 char *dir_home = NULL;
115 char *dir_engine_base = NULL;
116 char *dir_engine_info = NULL;
118 if (NULL == ut || (NULL != ut && 0 == strcmp(ut, "none"))) {
119 LOGE("[ERROR] Usertype is NONE");
123 uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
127 LOGD("uid(%d)", uid);
129 if (globalapp_uid == uid) {
131 dir_config_base = strdup(TTS_GLOBAL_CONFIG_BASE);
132 dir_home = strdup(TTS_GLOBAL_HOME);
133 dir_engine_base = strdup(TTS_GLOBAL_ENGINE_BASE);
134 dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
135 tmp_uid = 301; // app_fw
136 tmp_gid = 301; // app_fw
138 /* User app, Guest app, Security app */
139 if (NULL != g_dir_config_base)
140 dir_config_base = strdup(g_dir_config_base);
141 if (NULL != g_dir_home)
142 dir_home = strdup(g_dir_home);
143 if (NULL != g_dir_engine_base)
144 dir_engine_base = strdup(g_dir_engine_base);
145 if (NULL != g_dir_engine_info)
146 dir_engine_info = strdup(g_dir_engine_info);
151 if (NULL == dir_config_base || NULL == dir_home || NULL == dir_engine_base || NULL == dir_engine_info) {
152 LOGE("[ERROR] Fail to allocate memory");
153 FREE(dir_config_base)
155 FREE(dir_engine_base)
156 FREE(dir_engine_info)
161 LOGD("[DEBUG] dir_engine_info(%s)", dir_engine_info);
164 /* Make directories */
166 // if (0 != access(dir_config_base, F_OK)) {
167 fd = open(dir_config_base, O_DIRECTORY);
169 LOGE("[INFO] No directory : %s, errno : %d", dir_config_base, errno);
170 if (0 != mkdir(dir_config_base, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
171 LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_config_base, errno);
172 FREE(dir_config_base)
174 FREE(dir_engine_base)
175 FREE(dir_engine_info)
178 LOGD("Success to make directory : %s", dir_config_base);
179 if (0 != chown(dir_config_base, tmp_uid, tmp_gid)) {
180 LOGD("[ERROR] Fail to change user and group, errno : %d", errno);
182 LOGD("[DEBUG] Success to change user and group");
189 // if (0 != access(dir_home, F_OK)) {
190 fd = open(dir_home, O_DIRECTORY);
192 LOGE("[INFO] No directory : %s, errno : %d", dir_home, errno);
193 if (0 != mkdir(dir_home, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
194 LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_home, errno);
195 FREE(dir_config_base)
197 FREE(dir_engine_base)
198 FREE(dir_engine_info)
201 LOGD("Success to make directory : %s", dir_home);
202 if (0 != chown(dir_home, tmp_uid, tmp_gid)) {
203 LOGD("[ERROR] Fail to change user and group, errno : %d", errno);
205 LOGD("[DEBUG] Success to change user and group");
212 // if (0 != access(dir_engine_base, F_OK)) {
213 fd = open(dir_engine_base, O_DIRECTORY);
215 LOGE("[INFO] No directory : %s, errno : %d", dir_engine_base, errno);
216 if (0 != mkdir(dir_engine_base, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
217 LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_engine_base, errno);
218 FREE(dir_config_base)
220 FREE(dir_engine_base)
221 FREE(dir_engine_info)
224 LOGD("Success to make directory : %s", dir_engine_base);
225 if (0 != chown(dir_engine_base, tmp_uid, tmp_gid)) {
226 LOGD("[ERROR] Fail to change user and group, errno : %d", errno);
228 LOGD("[DEBUG] Success to change user and group");
235 // if (0 != access(dir_engine_info, F_OK)) {
236 fd = open(dir_engine_info, O_DIRECTORY);
238 LOGE("[INFO] No directory : %s, errno : %d", dir_engine_info, errno);
239 if (0 != mkdir(dir_engine_info, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
240 LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_engine_info, errno);
241 FREE(dir_config_base)
243 FREE(dir_engine_base)
244 FREE(dir_engine_info)
247 LOGD("Success to make directory : %s", dir_engine_info);
248 if (0 != chown(dir_engine_info, tmp_uid, tmp_gid)) {
249 LOGD("[ERROR] Fail to change user and group, errno : %d", errno);
251 LOGD("[DEBUG] Success to change user and group");
259 char path[256] = {'\0',};
260 snprintf(path, 256, "%s/%s.xml", dir_engine_info, pkgid);
261 int ret = xmlSaveFormatFile(path, g_doc, 1);
262 LOGD("xmlSaveFile (%d)", ret);
264 if (0 != chown(path, tmp_uid, tmp_gid)) {
265 LOGD("[ERROR] Fail to change user and group");
267 LOGD("[DEBUG] Success to change user and group");
271 FREE(dir_config_base)
273 FREE(dir_engine_base)
274 FREE(dir_engine_info)
280 static int __remove_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid)
282 LOGD("@@@ Remove engine info doc");
284 char *dir_engine_info = NULL;
286 if (NULL == ut || (NULL != ut && 0 == strcmp(ut, "none"))) {
287 LOGE("[ERROR] Usertype is NONE");
291 uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
293 LOGD("uid(%d)", uid);
295 if (globalapp_uid == uid) {
297 dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
299 /* User app, Guest app, Security app */
300 if (NULL != g_dir_engine_info)
301 dir_engine_info = strdup(g_dir_engine_info);
304 if (NULL == dir_engine_info) {
305 LOGE("[ERROR] Fail to allocate memory");
309 LOGD("[DEBUG] dir_engine_info(%s)", dir_engine_info);
312 char path[256] = {'\0',};
313 snprintf(path, 256, "%s/%s.xml", dir_engine_info, pkgid);
314 if (0 == access(path, F_OK)) {
315 LOGD("Remove engine info xml(%s)", path);
316 if (0 != remove(path)) {
317 LOGE("[ERROR] Fail to Remove engine info xml(%s)", path);
321 FREE(dir_engine_info)
327 static void __insert_language_from_metadata(xmlNodePtr root, const char *language)
329 LOGD("@@@ Insert language");
333 if (NULL == root || NULL == language) {
334 LOGE("Invalid parameter, root(%p), language(%s)", root, language);
338 char *tmp_lang = NULL;
339 char *tmp_free = NULL;
340 tmp_free = tmp_lang = strdup(language);
341 if (NULL == tmp_lang) {
342 LOGE("Fail to memory allocation");
345 xmlNodePtr voices_node = NULL;
346 xmlNodePtr voice_node = NULL;
348 voices_node = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_VOICE_SET);
350 voice = strsep(&tmp_lang, ",");
351 while (NULL != voice) {
352 LOGD("voice (%s)", voice);
353 voice_node = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_VOICE);
354 lang = strsep(&voice, ":");
355 LOGD("lang (%s)", lang);
356 type = strsep(&voice, " ");
357 LOGD("type (%s)", type);
358 xmlSetProp(voice_node, (const xmlChar*)TTS_TAG_ENGINE_VOICE_TYPE, (const xmlChar*)type);
359 xmlNodeSetContent(voice_node, (const xmlChar*)lang);
360 xmlAddChild(voices_node, voice_node);
361 voice = strsep(&tmp_lang, ",");
363 xmlAddChild(root, voices_node);
368 static int __write_metadata_inxml(const char *pkgid, const char *appid, GList *list)
373 bool isTextsize = false;
375 __create_engine_info_xml(pkgid);
377 xmlNodePtr root = NULL;
378 xmlNodePtr cur = NULL;
380 root = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_BASE);
382 LOGE("[ERROR] Fail to get new node");
383 // xmlFreeDoc(g_doc);
386 xmlDocSetRootElement(g_doc, root);
389 // cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_NAME);
390 // xmlNodeSetContent(cur, (const xmlChar*)pkgid);
391 // xmlAddChild(root, cur);
394 iter = g_list_first(list);
395 while (NULL != iter) {
396 md = (metadata *)iter->data;
397 if (NULL != md && NULL != md->key) {
398 LOGD(" - key(%s) value(%s)", md->key, md->value);
399 if (!strcmp(md->key, TTS_METADATA_LANGUAGE)) {
400 __insert_language_from_metadata(root, md->value);
401 } else if (!strcmp(md->key, TTS_METADATA_CREDENTIAL_REQUIRED)) {
402 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_CREDENTIAL);
403 xmlNodeSetContent(cur, (const xmlChar*)md->value);
404 xmlAddChild(root, cur);
405 } else if (!strcmp(md->key, TTS_METADATA_SETTING)) {
406 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_SETTING);
407 xmlNodeSetContent(cur, (const xmlChar*)md->value);
408 xmlAddChild(root, cur);
409 } else if (!strcmp(md->key, TTS_METADATA_NAME)) {
410 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_NAME);
411 xmlNodeSetContent(cur, (const xmlChar*)md->value);
412 xmlAddChild(root, cur);
413 } else if (!strcmp(md->key, TTS_METADATA_TEXT_SIZE)) {
414 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_TEXT_SIZE);
415 xmlNodeSetContent(cur, (const xmlChar*)md->value);
416 xmlAddChild(root, cur);
418 } else if (!strcmp(md->key, TTS_METADATA_PITCH_SUPPORT)) {
419 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_PITCH_SUPPORT);
420 xmlNodeSetContent(cur, (const xmlChar*)md->value);
421 xmlAddChild(root, cur);
423 LOGW("[WARNING] Unknown metadata type");
426 iter = g_list_next(iter);
429 if (false == isTextsize) {
430 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_TEXT_SIZE);
431 xmlNodeSetContent(cur, (const xmlChar*)TTS_MAX_TEXT_SIZE);
432 xmlAddChild(root, cur);
433 LOGD("[DEBUG] Max text size is set as %s.", TTS_MAX_TEXT_SIZE);
436 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_ID);
437 xmlNodeSetContent(cur, (const xmlChar*)pkgid);
438 xmlAddChild(root, cur);
447 int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
449 LOGD("METADATA INSTALL");
450 LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
453 ret = pkgmgr_installer_info_get_target_uid(&g_uid);
455 LOGE("[ERROR] Fail to get target uid");
458 LOGD("uid(%d)", g_uid);
459 printf("[Parser Debug][DEBUG] uid(%d)", g_uid);
462 uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
463 if (globalapp_uid == g_uid) {
464 g_user_type = g_strdup("admin");
466 g_guser = gum_user_get_sync(g_uid, FALSE);
467 if (NULL == g_guser) {
468 LOGE("[ERROR] g_guser is NULL");
472 g_object_get(G_OBJECT(g_guser), "gid", &g_gid, NULL);
473 g_object_get(G_OBJECT(g_guser), "usertype", &g_ut, NULL);
474 g_user_type = g_strdup(gum_user_type_to_string(g_ut));
477 if (NULL == g_user_type) {
478 LOGE("[ERROR] Fail to allocate memory");
479 if (NULL != g_guser) {
480 g_object_unref(g_guser);
486 if (0 == strcmp(g_user_type, "none")) {
487 /* GUM_USERTYPE_NONE */
488 LOGE("[ERROR] Fail to get target uid");
489 g_object_unref(g_guser);
495 if (globalapp_uid == g_uid) {
496 /* global directory */
497 LOGD("[DEBUG] usertype: %s", g_user_type);
498 if (0 >= g_list_length(list)) {
499 LOGE("[ERROR] No Engine Metadata");
504 if (0 != __write_metadata_inxml(pkgid, appid, list)) {
505 LOGE("[ERROR] Fail to write metadata in the xml");
511 /* Save in /etc/skel/share/ */
512 g_dir_config_base = strdup(TTS_GLOBAL_CONFIG_BASE);
513 g_dir_home = strdup(TTS_GLOBAL_HOME);
514 g_dir_engine_base = strdup(TTS_GLOBAL_ENGINE_BASE);
515 g_dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
517 if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) {
518 LOGE("[ERROR] Fail to allocate memory");
519 FREE(g_dir_config_base)
521 FREE(g_dir_engine_base)
522 FREE(g_dir_engine_info)
529 if (0 != __save_engine_info_xml(pkgid, g_user_type, g_uid, g_gid)) {
530 LOGE("[ERROR] Fail to make engine info file");
536 /* Get user data by using libgum */
538 GumUserService *gus = NULL;
539 GumUserList *users = NULL;
540 GumUserList *iter = NULL;
541 GumUser *user = NULL;
543 GumUserType gumut = GUM_USERTYPE_NONE;
544 gchar *user_type = NULL;
548 gchar *home_dir = NULL;
550 gus = gum_user_service_create_sync(TRUE);
552 LOGE("Failed to create gum user service");
557 query = g_strsplit("admin,normal", ",", -1);
559 users = gum_user_service_get_user_list_sync(gus, (const gchar *const *)query);
570 /* Make new user list */
573 while (iter != NULL) {
574 user = (GumUser*) iter->data;
575 g_object_get(G_OBJECT(user), "uid", &uid, NULL);
578 g_object_get(G_OBJECT(user), "gid", &gid, NULL);
579 g_object_get(G_OBJECT(user), "homedir", &home_dir, NULL);
580 g_object_get(G_OBJECT(user), "usertype", &gumut, NULL);
581 user_type = g_strdup(gum_user_type_to_string(gumut));
582 if (NULL == user_type) {
583 gum_user_service_list_free(users);
590 LOGD("[DEBUG] user info");
591 if (NULL != home_dir) {
592 LOGD("[DEBUG] uid(%d), gid(%d), user_type(%s), home_dir(%s)", uid, gid, user_type, home_dir);
594 g_dir_config_base = (char*)calloc(strlen(home_dir) + 14, sizeof(char));
595 g_dir_home = (char*)calloc(strlen(home_dir) + 18, sizeof(char));
596 g_dir_engine_base = (char*)calloc(strlen(home_dir) + 22, sizeof(char));
597 g_dir_engine_info = (char*)calloc(strlen(home_dir) + 34, sizeof(char));
599 if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) {
600 LOGE("[ERROR] Fail to allocate memory");
601 FREE(g_dir_config_base)
603 FREE(g_dir_engine_base)
604 FREE(g_dir_engine_info)
605 gum_user_service_list_free(users);
612 snprintf(g_dir_config_base, strlen(home_dir) + 14, "%s/share/.voice", home_dir);
613 snprintf(g_dir_home, strlen(home_dir) + 18, "%s/share/.voice/tts", home_dir);
614 snprintf(g_dir_engine_base, strlen(home_dir) + 22, "%s/share/.voice/tts/1.0", home_dir);
615 snprintf(g_dir_engine_info, strlen(home_dir) + 34, "%s/share/.voice/tts/1.0/engine-info", home_dir);
617 LOGD("[DEBUG] g_dir_engine_info(%s)", g_dir_engine_info);
619 if (0 != __save_engine_info_xml(pkgid, user_type, uid, gid)) {
620 LOGE("[ERROR] Fail to make engine info file");
623 FREE(g_dir_config_base)
625 FREE(g_dir_engine_base)
626 FREE(g_dir_engine_info)
632 iter = g_list_next(iter);
635 gum_user_service_list_free(users);
640 LOGD("[DEBUG] usertype: %s", g_user_type);
642 ret = tzplatform_set_user(g_uid);
644 LOGE("[ERROR] Invalid uid");
645 g_object_unref(g_guser);
650 LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
651 printf("[Parser Debug][DEBUG] TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
654 if (0 >= g_list_length(list)) {
655 LOGE("[ERROR] No Engine Metadata");
656 g_object_unref(g_guser);
662 if (0 != __write_metadata_inxml(pkgid, appid, list)) {
663 LOGE("[ERROR] Fail to write metadata in the xml");
665 g_object_unref(g_guser);
671 g_dir_config_base = strdup(TTS_CONFIG_BASE);
672 g_dir_home = strdup(TTS_HOME);
673 g_dir_engine_base = strdup(TTS_ENGINE_BASE);
674 g_dir_engine_info = strdup(TTS_ENGINE_INFO);
676 if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) {
677 LOGE("[ERROR] Fail to allocate memory");
678 FREE(g_dir_config_base)
680 FREE(g_dir_engine_base)
681 FREE(g_dir_engine_info)
683 g_object_unref(g_guser);
689 if (0 != __save_engine_info_xml(pkgid, g_user_type, g_uid, g_gid)) {
690 LOGE("[ERROR] Fail to make engine info file");
692 if (NULL != g_guser) {
693 g_object_unref(g_guser);
702 if (NULL != g_guser) {
703 g_object_unref(g_guser);
708 FREE(g_dir_config_base)
710 FREE(g_dir_engine_base)
711 FREE(g_dir_engine_info)
717 int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
719 LOGD("METADATA UNINSTALL");
720 LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
723 ret = pkgmgr_installer_info_get_target_uid(&g_uid);
725 LOGE("[ERROR] Fail to get target uid");
728 LOGD("uid(%d)", g_uid);
729 printf("[Parser Debug][DEBUG] uid(%d)", g_uid);
732 uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
733 if (globalapp_uid == g_uid) {
734 g_user_type = g_strdup("admin");
735 LOGD("[DEBUG] g_user_type: %s (%d)", g_user_type, globalapp_uid);
737 LOGD("[DEBUG] globalapp_uid(%d)", globalapp_uid);
739 g_guser = gum_user_get_sync(g_uid, FALSE);
740 if (NULL == g_guser) {
741 LOGE("[ERROR] g_guser is NULL");
745 g_object_get(G_OBJECT(g_guser), "usertype", &g_ut, NULL);
746 g_user_type = g_strdup(gum_user_type_to_string(g_ut));
748 LOGD("[DEBUG] g_guser(%s), g_ut(%s), g_user_type(%s)", g_guser, g_ut, g_user_type);
751 if (NULL == g_user_type) {
752 LOGE("[ERROR] Fail to allocate memory");
753 if (NULL != g_guser) {
754 g_object_unref(g_guser);
760 if (0 == strcmp(g_user_type, "none")) {
761 /* GUM_USERTYPE_NONE */
762 LOGE("[ERROR] Fail to get target uid");
763 g_object_unref(g_guser);
769 if (globalapp_uid == g_uid) {
770 /* global directory */
771 LOGD("[DEBUG] usertype: %s", g_user_type);
773 /* Remove files in /etc/skel/share/ */
774 g_dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
775 if (NULL == g_dir_engine_info) {
776 LOGE("[ERROR] Fail to allocate memory");
781 if (0 != __remove_engine_info_xml(pkgid, g_user_type, g_uid)) {
782 LOGE("[ERROR] Fail to remove engine info file");
785 /* Get user data by using libgum */
787 GumUserService *gus = NULL;
788 GumUserList *users = NULL;
789 GumUserList *iter = NULL;
790 GumUser *user = NULL;
792 GumUserType gumut = GUM_USERTYPE_NONE;
793 gchar *user_type = NULL;
796 gchar *home_dir = NULL;
798 GList *md_iter = NULL;
801 gus = gum_user_service_create_sync(TRUE);
803 LOGE("Failed to create gum user service");
808 query = g_strsplit("admin,normal", ",", -1);
810 users = gum_user_service_get_user_list_sync(gus, (const gchar *const *)query);
821 /* Make new user list */
824 while (iter != NULL) {
825 user = (GumUser*) iter->data;
826 g_object_get(G_OBJECT(user), "uid", &uid, NULL);
828 g_object_get(G_OBJECT(user), "homedir", &home_dir, NULL);
829 g_object_get(G_OBJECT(user), "usertype", &gumut, NULL);
830 user_type = g_strdup(gum_user_type_to_string(gumut));
831 if (NULL == user_type) {
832 gum_user_service_list_free(users);
839 if (NULL != home_dir) {
840 g_dir_engine_info = (char*)calloc(strlen(home_dir) + 34, sizeof(char));
841 if (NULL == g_dir_engine_info) {
842 gum_user_service_list_free(users);
850 snprintf(g_dir_engine_info, strlen(home_dir) + 34, "%s/share/.voice/tts/1.0/engine-info", home_dir);
852 md_iter = g_list_first(list);
853 while (NULL != md_iter) {
854 md = (metadata *)md_iter->data;
855 LOGD(" - key(%s) value(%s)", md->key, md->value);
856 md_iter = g_list_next(md_iter);
859 if (0 != __remove_engine_info_xml(pkgid, user_type, uid)) {
860 LOGE("[ERROR] Fail to remove engine info file");
864 FREE(g_dir_engine_info)
868 LOGD("Finish release memory");
869 iter = g_list_next(iter);
870 LOGD("Finish next iter");
873 gum_user_service_list_free(users);
878 LOGD("[DEBUG] usertype: %s", g_user_type);
880 ret = tzplatform_set_user(g_uid);
882 LOGE("[ERROR] Invalid uid");
883 g_object_unref(g_guser);
888 LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
889 printf("[Parser Debug][DEBUG] TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
892 g_dir_engine_info = strdup(TTS_ENGINE_INFO);
893 if (NULL == g_dir_engine_info) {
894 LOGE("[ERROR] Fail to allocate memory");
895 g_object_unref(g_guser);
901 if (0 != __remove_engine_info_xml(pkgid, g_user_type, g_uid)) {
902 LOGE("[ERROR] Fail to remove engine info file");
907 if (NULL != g_guser) {
908 g_object_unref(g_guser);
913 FREE(g_dir_engine_info)
920 int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
922 LOGD("METADATA UPGRADE");
923 LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
925 PKGMGR_MDPARSER_PLUGIN_UNINSTALL(pkgid, appid, list);
926 PKGMGR_MDPARSER_PLUGIN_INSTALL(pkgid, appid, list);