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>
28 #include <tzplatform_config.h>
29 #include <systemd/sd-login.h>
31 #include <gum/gum-user.h>
32 #include <gum/gum-user-service.h>
33 #include <gum/common/gum-user-types.h>
35 /* Define EXPORT_API */
37 #define EXPORT_API __attribute__((visibility("default")))
43 #define LOG_TAG "tts-engine-parser"
45 #define TTS_TAG_ENGINE_BASE "tts-engine"
46 #define TTS_TAG_ENGINE_NAME "name"
47 #define TTS_TAG_ENGINE_ID "id"
48 #define TTS_TAG_ENGINE_SETTING "setting"
49 #define TTS_TAG_ENGINE_VOICE_SET "voices"
50 #define TTS_TAG_ENGINE_VOICE "voice"
51 #define TTS_TAG_ENGINE_VOICE_TYPE "type"
52 #define TTS_TAG_ENGINE_PITCH_SUPPORT "pitch-support"
53 #define TTS_TAG_ENGINE_CREDENTIAL "credential"
55 #define TTS_CONFIG_BASE tzplatform_mkpath(TZ_USER_HOME, "share/.voice")
56 #define TTS_HOME tzplatform_mkpath(TZ_USER_HOME, "share/.voice/tts")
57 #define TTS_ENGINE_BASE tzplatform_mkpath(TZ_USER_HOME, "share/.voice/tts/1.0")
58 #define TTS_ENGINE_INFO tzplatform_mkpath(TZ_USER_SHARE, ".voice/tts/1.0/engine-info")
60 #define TTS_GLOBAL_CONFIG_BASE "/etc/skel/share/.voice"
61 #define TTS_GLOBAL_HOME "/etc/skel/share/.voice/tts"
62 #define TTS_GLOBAL_ENGINE_BASE "/etc/skel/share/.voice/tts/1.0"
63 #define TTS_GLOBAL_ENGINE_INFO "/etc/skel/share/.voice/tts/1.0/engine-info"
65 #define TTS_METADATA_LANGUAGE "http://tizen.org/metadata/tts-engine/language"
66 #define TTS_METADATA_CREDENTIAL_REQUIRED "http://tizen.org/metadata/tts-engine/credential-required"
69 typedef struct metadata {
74 static xmlDocPtr g_doc;
75 GumUser *g_guser = NULL;
77 GumUserType g_ut = GUM_USERTYPE_NONE;
78 gchar *g_user_type = NULL;
80 char *g_dir_config_base = NULL;
81 char *g_dir_home = NULL;
82 char *g_dir_engine_base = NULL;
83 char *g_dir_engine_info = NULL;
85 static int __create_engine_info_xml(const char *pkgid)
87 LOGD("=== Create engine info doc");
88 g_doc = xmlNewDoc((xmlChar*)"1.0");
90 LOGE("[ERROR] Fail to new doc");
97 static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid)
99 LOGD("=== Save engine info doc");
100 char *dir_config_base = NULL;
101 char *dir_home = NULL;
102 char *dir_engine_base = NULL;
103 char *dir_engine_info = NULL;
105 if (NULL == ut || (NULL != ut && 0 == strcmp(ut, "none"))) {
106 LOGE("[ERROR] Usertype is NONE");
110 uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
112 LOGD("uid(%d)", uid);
114 if (globalapp_uid == uid) {
116 dir_config_base = strdup(TTS_GLOBAL_CONFIG_BASE);
117 dir_home = strdup(TTS_GLOBAL_HOME);
118 dir_engine_base = strdup(TTS_GLOBAL_ENGINE_BASE);
119 dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
121 /* User app, Guest app, Security app */
122 if (NULL != g_dir_config_base)
123 dir_config_base = strdup(g_dir_config_base);
124 if (NULL != g_dir_home)
125 dir_home = strdup(g_dir_home);
126 if (NULL != g_dir_engine_base)
127 dir_engine_base = strdup(g_dir_engine_base);
128 if (NULL != g_dir_engine_info)
129 dir_engine_info = strdup(g_dir_engine_info);
132 if (NULL == dir_config_base || NULL == dir_home || NULL == dir_engine_base || NULL == dir_engine_info) {
133 LOGE("[ERROR] Fail to allocate memory");
134 if (NULL != dir_config_base) {
135 free(dir_config_base);
136 dir_config_base = NULL;
138 if (NULL != dir_home) {
142 if (NULL != dir_engine_base) {
143 free(dir_engine_base);
144 dir_engine_base = NULL;
146 if (NULL != dir_engine_info) {
147 free(dir_engine_info);
148 dir_engine_info = NULL;
153 LOGD("[DEBUG] dir_engine_info(%s)", dir_engine_info);
156 /* Make directories */
157 if (0 != access(dir_config_base, F_OK)) {
158 if (0 != mkdir(dir_config_base, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
159 LOGE("[ERROR] Fail to make directory : %s", dir_config_base);
160 free(dir_config_base);
161 dir_config_base = NULL;
164 free(dir_engine_base);
165 dir_engine_base = NULL;
166 free(dir_engine_info);
167 dir_engine_info = NULL;
170 LOGD("Success to make directory : %s", dir_config_base);
174 if (0 != access(dir_home, F_OK)) {
175 if (0 != mkdir(dir_home, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
176 LOGE("[ERROR] Fail to make directory : %s", dir_home);
177 free(dir_config_base);
178 dir_config_base = NULL;
181 free(dir_engine_base);
182 dir_engine_base = NULL;
183 free(dir_engine_info);
184 dir_engine_info = NULL;
187 LOGD("Success to make directory : %s", dir_home);
191 if (0 != access(dir_engine_base, F_OK)) {
192 if (0 != mkdir(dir_engine_base, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
193 LOGE("[ERROR] Fail to make directory : %s", dir_engine_base);
194 free(dir_config_base);
195 dir_config_base = NULL;
198 free(dir_engine_base);
199 dir_engine_base = NULL;
200 free(dir_engine_info);
201 dir_engine_info = NULL;
204 LOGD("Success to make directory : %s", dir_engine_base);
208 if (0 != access(dir_engine_info, F_OK)) {
209 if (0 != mkdir(dir_engine_info, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
210 LOGE("[ERROR] Fail to make directory : %s", dir_engine_info);
211 free(dir_config_base);
212 dir_config_base = NULL;
215 free(dir_engine_base);
216 dir_engine_base = NULL;
217 free(dir_engine_info);
218 dir_engine_info = NULL;
221 LOGD("Success to make directory : %s", dir_engine_info);
226 char path[256] = {'\0',};
227 snprintf(path, 256, "%s/%s.xml", dir_engine_info, pkgid);
228 int ret = xmlSaveFormatFile(path, g_doc, 1);
229 LOGD("xmlSaveFile (%d)", ret);
231 free(dir_config_base);
232 dir_config_base = NULL;
235 free(dir_engine_base);
236 dir_engine_base = NULL;
237 free(dir_engine_info);
238 dir_engine_info = NULL;
244 static int __remove_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid)
246 LOGD("=== Remove engine info doc");
248 char *dir_engine_info = NULL;
250 if (NULL == ut || (NULL != ut && 0 == strcmp(ut, "none"))) {
251 LOGE("[ERROR] Usertype is NONE");
255 uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
257 LOGD("uid(%d)", uid);
259 if (globalapp_uid == uid) {
261 dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
263 /* User app, Guest app, Security app */
264 if (NULL != g_dir_engine_info)
265 dir_engine_info = strdup(g_dir_engine_info);
268 if (NULL == dir_engine_info) {
269 LOGE("[ERROR] Fail to allocate memory");
273 LOGD("[DEBUG] dir_engine_info(%s)", dir_engine_info);
276 char path[256] = {'\0',};
277 snprintf(path, 256, "%s/%s.xml", dir_engine_info, pkgid);
278 if (0 == access(path, F_OK)) {
279 LOGD("Remove engine info xml(%s)", path);
280 if (0 != remove(path)) {
281 LOGE("[ERROR] Fail to Remove engine info xml(%s)", path);
285 free(dir_engine_info);
286 dir_engine_info = NULL;
292 static void __insert_language_from_metadata(xmlNodePtr root, const char *language)
294 LOGD("==== Insert language");
299 char *tmp_lang = NULL;
300 char *tmp_free = NULL;
301 tmp_free = tmp_lang = strdup(language);
302 if (NULL == tmp_lang) {
303 LOGE("Fail to memory allocation");
306 xmlNodePtr voices_node = NULL;
307 xmlNodePtr voice_node = NULL;
309 voices_node = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_VOICE_SET);
311 voice = strsep(&tmp_lang, ",");
312 while (NULL != voice) {
313 LOGD("voice (%s)", voice);
314 voice_node = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_VOICE);
315 lang = strsep(&voice, ":");
316 LOGD("lang (%s)", lang);
317 type = strsep(&voice, " ");
318 LOGD("type (%s)", type);
319 xmlSetProp(voice_node, (const xmlChar*)TTS_TAG_ENGINE_VOICE_TYPE, (const xmlChar*)type);
320 xmlNodeSetContent(voice_node, (const xmlChar*)lang);
321 xmlAddChild(voices_node, voice_node);
322 voice = strsep(&tmp_lang, ",");
324 xmlAddChild(root, voices_node);
330 static int __write_metadata_inxml(const char *pkgid, const char *appid, GList *list)
335 __create_engine_info_xml(pkgid);
337 xmlNodePtr root = NULL;
338 xmlNodePtr cur = NULL;
340 root = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_BASE);
342 LOGE("[ERROR] Fail to get new node");
343 // xmlFreeDoc(g_doc);
346 xmlDocSetRootElement(g_doc, root);
349 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_NAME);
350 xmlNodeSetContent(cur, (const xmlChar*)pkgid);
351 xmlAddChild(root, cur);
354 iter = g_list_first(list);
355 while (NULL != iter) {
356 md = (metadata *)iter->data;
357 if (NULL != md && NULL != md->key) {
358 LOGD(" - key(%s) value(%s)", md->key, md->value);
359 if (!strcmp(md->key, TTS_METADATA_LANGUAGE)) {
360 __insert_language_from_metadata(root, md->value);
361 } else if (!strcmp(md->key, TTS_METADATA_CREDENTIAL_REQUIRED)) {
362 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_CREDENTIAL);
363 xmlNodeSetContent(cur, (const xmlChar*)md->value);
364 xmlAddChild(root, cur);
366 LOGW("[WARNING] Unknown metadata type");
369 iter = g_list_next(iter);
372 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_ID);
373 xmlNodeSetContent(cur, (const xmlChar*)pkgid);
374 xmlAddChild(root, cur);
383 int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
385 LOGD("METADATA INSTALL");
386 LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
389 ret = pkgmgr_installer_info_get_target_uid(&g_uid);
391 LOGE("[ERROR] Fail to get target uid");
394 LOGD("uid(%d)", g_uid);
395 printf("[Parser Debug][DEBUG] uid(%d)", g_uid);
398 uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
399 if (globalapp_uid == g_uid) {
400 g_user_type = g_strdup("admin");
402 g_guser = gum_user_get_sync(g_uid, FALSE);
403 if (NULL == g_guser) {
404 LOGE("[ERROR] g_guser is NULL");
408 g_object_get(G_OBJECT(g_guser), "usertype", &g_ut, NULL);
409 g_user_type = g_strdup(gum_user_type_to_string(g_ut));
412 if (NULL == g_user_type) {
413 LOGE("[ERROR] Fail to allocate memory");
414 if (NULL != g_guser) {
415 g_object_unref(g_guser);
421 if (0 == strcmp(g_user_type, "none")) {
422 /* GUM_USERTYPE_NONE */
423 LOGE("[ERROR] Fail to get target uid");
424 g_object_unref(g_guser);
430 if (globalapp_uid == g_uid) {
431 /* global directory */
432 LOGD("[DEBUG] usertype: %s", g_user_type);
433 if (0 >= g_list_length(list)) {
434 LOGE("[ERROR] No Engine Metadata");
439 if (0 != __write_metadata_inxml(pkgid, appid, list)) {
440 LOGE("[ERROR] Fail to write metadata in the xml");
446 /* Save in /etc/skel/share/ */
447 g_dir_config_base = strdup(TTS_GLOBAL_CONFIG_BASE);
448 g_dir_home = strdup(TTS_GLOBAL_HOME);
449 g_dir_engine_base = strdup(TTS_GLOBAL_ENGINE_BASE);
450 g_dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
452 if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) {
453 LOGE("[ERROR] Fail to allocate memory");
454 if (NULL != g_dir_config_base) {
455 free(g_dir_config_base);
456 g_dir_config_base = NULL;
458 if (NULL != g_dir_home) {
462 if (NULL != g_dir_engine_base) {
463 free(g_dir_engine_base);
464 g_dir_engine_base = NULL;
466 if (NULL != g_dir_engine_info) {
467 free(g_dir_engine_info);
468 g_dir_engine_info = NULL;
475 if (0 != __save_engine_info_xml(pkgid, g_user_type, g_uid)) {
476 LOGE("[ERROR] Fail to make engine info file");
482 /* Get user data by using libgum */
484 GumUserService *gus = NULL;
485 GumUserList *users = NULL;
486 GumUserList *iter = NULL;
487 GumUser *user = NULL;
489 GumUserType gumut = GUM_USERTYPE_NONE;
490 gchar *user_type = NULL;
493 gchar *home_dir = NULL;
495 gus = gum_user_service_create_sync(TRUE);
497 LOGE("Failed to create gum user service");
502 query = g_strsplit("admin,normal", ",", -1);
504 users = gum_user_service_get_user_list_sync(gus, (const gchar *const *)query);
508 LOGE("Failed to get gum user list");
515 /* Make new user list */
518 while (iter != NULL) {
519 user = (GumUser*) iter->data;
520 g_object_get(G_OBJECT(user), "uid", &uid, NULL);
521 if (NULL != home_dir) {
525 g_object_get(G_OBJECT(user), "homedir", &home_dir, NULL);
526 g_object_get(G_OBJECT(user), "usertype", &gumut, NULL);
527 user_type = g_strdup(gum_user_type_to_string(gumut));
528 if (NULL == user_type) {
529 gum_user_service_list_free(users);
535 LOGD("[DEBUG] user info");
536 if (NULL != home_dir) {
537 LOGD("[DEBUG] uid(%d), user_type(%s), home_dir(%s)", uid, user_type, home_dir);
539 g_dir_config_base = (char*)calloc(strlen(home_dir) + 14, sizeof(char));
540 g_dir_home = (char*)calloc(strlen(home_dir) + 18, sizeof(char));
541 g_dir_engine_base = (char*)calloc(strlen(home_dir) + 22, sizeof(char));
542 g_dir_engine_info = (char*)calloc(strlen(home_dir) + 34, sizeof(char));
544 if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) {
545 LOGE("[ERROR] Fail to allocate memory");
546 if (NULL != g_dir_config_base) {
547 free(g_dir_config_base);
548 g_dir_config_base = NULL;
550 if (NULL != g_dir_home) {
554 if (NULL != g_dir_engine_base) {
555 free(g_dir_engine_base);
556 g_dir_engine_base = NULL;
558 if (NULL != g_dir_engine_info) {
559 free(g_dir_engine_info);
560 g_dir_engine_info = NULL;
562 gum_user_service_list_free(users);
567 snprintf(g_dir_config_base, strlen(home_dir) + 14, "%s/share/.voice", home_dir);
568 snprintf(g_dir_home, strlen(home_dir) + 18, "%s/share/.voice/tts", home_dir);
569 snprintf(g_dir_engine_base, strlen(home_dir) + 22, "%s/share/.voice/tts/1.0", home_dir);
570 snprintf(g_dir_engine_info, strlen(home_dir) + 34, "%s/share/.voice/tts/1.0/engine-info", home_dir);
572 LOGD("[DEBUG] g_dir_engine_info(%s)", g_dir_engine_info);
574 if (0 != __save_engine_info_xml(pkgid, user_type, uid)) {
575 LOGE("[ERROR] Fail to make engine info file");
578 free(g_dir_config_base);
579 g_dir_config_base = NULL;
582 free(g_dir_engine_base);
583 g_dir_engine_base = NULL;
584 free(g_dir_engine_info);
585 g_dir_engine_info = NULL;
592 iter = g_list_next(iter);
594 iter = g_list_next(iter);
597 if (NULL != user_type) {
603 gum_user_service_list_free(users);
608 LOGD("[DEBUG] usertype: %s", g_user_type);
610 ret = tzplatform_set_user(g_uid);
612 LOGE("[ERROR] Invalid uid");
613 g_object_unref(g_guser);
618 LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
619 printf("[Parser Debug][DEBUG] TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
622 if (0 >= g_list_length(list)) {
623 LOGE("[ERROR] No Engine Metadata");
624 g_object_unref(g_guser);
630 if (0 != __write_metadata_inxml(pkgid, appid, list)) {
631 LOGE("[ERROR] Fail to write metadata in the xml");
633 g_object_unref(g_guser);
639 g_dir_config_base = strdup(TTS_CONFIG_BASE);
640 g_dir_home = strdup(TTS_HOME);
641 g_dir_engine_base = strdup(TTS_ENGINE_BASE);
642 g_dir_engine_info = strdup(TTS_ENGINE_INFO);
644 if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) {
645 LOGE("[ERROR] Fail to allocate memory");
646 if (NULL != g_dir_config_base) {
647 free(g_dir_config_base);
648 g_dir_config_base = NULL;
650 if (NULL != g_dir_home) {
654 if (NULL != g_dir_engine_base) {
655 free(g_dir_engine_base);
656 g_dir_engine_base = NULL;
658 if (NULL != g_dir_engine_info) {
659 free(g_dir_engine_info);
660 g_dir_engine_info = NULL;
663 g_object_unref(g_guser);
669 if (0 != __save_engine_info_xml(pkgid, g_user_type, g_uid)) {
670 LOGE("[ERROR] Fail to make engine info file");
672 if (NULL != g_guser) {
673 g_object_unref(g_guser);
682 if (NULL != g_guser) {
683 g_object_unref(g_guser);
688 if (NULL != g_dir_config_base) {
689 free(g_dir_config_base);
690 g_dir_config_base = NULL;
692 if (NULL != g_dir_home) {
696 if (NULL != g_dir_engine_base) {
697 free(g_dir_engine_base);
698 g_dir_engine_base = NULL;
700 if (NULL != g_dir_engine_info) {
701 free(g_dir_engine_info);
702 g_dir_engine_info = NULL;
709 int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
711 LOGD("METADATA UNINSTALL");
712 LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
715 ret = pkgmgr_installer_info_get_target_uid(&g_uid);
717 LOGE("[ERROR] Fail to get target uid");
720 LOGD("uid(%d)", g_uid);
721 printf("[Parser Debug][DEBUG] uid(%d)", g_uid);
724 uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
725 if (globalapp_uid == g_uid) {
726 g_user_type = g_strdup("admin");
728 g_guser = gum_user_get_sync(g_uid, FALSE);
729 if (NULL == g_guser) {
730 LOGE("[ERROR] g_guser is NULL");
734 g_object_get(G_OBJECT(g_guser), "usertype", &g_ut, NULL);
735 g_user_type = g_strdup(gum_user_type_to_string(g_ut));
738 if (NULL == g_user_type) {
739 LOGE("[ERROR] Fail to allocate memory");
740 if (NULL != g_guser) {
741 g_object_unref(g_guser);
747 if (0 == strcmp(g_user_type, "none")) {
748 /* GUM_USERTYPE_NONE */
749 LOGE("[ERROR] Fail to get target uid");
750 g_object_unref(g_guser);
756 if (globalapp_uid == g_uid) {
757 /* global directory */
758 LOGD("[DEBUG] usertype: %s", g_user_type);
760 /* Remove files in /etc/skel/share/ */
761 g_dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
762 if (NULL == g_dir_engine_info) {
763 LOGE("[ERROR] Fail to allocate memory");
768 if (0 != __remove_engine_info_xml(pkgid, g_user_type, g_uid)) {
769 LOGE("[ERROR] Fail to remove engine info file");
772 /* Get user data by using libgum */
774 GumUserService *gus = NULL;
775 GumUserList *users = NULL;
776 GumUserList *iter = NULL;
777 GumUser *user = NULL;
779 GumUserType gumut = GUM_USERTYPE_NONE;
780 gchar *user_type = NULL;
783 gchar *home_dir = NULL;
785 GList *md_iter = NULL;
788 gus = gum_user_service_create_sync(TRUE);
790 LOGE("Failed to create gum user service");
795 query = g_strsplit("admin,normal", ",", -1);
797 users = gum_user_service_get_user_list_sync(gus, (const gchar *const *)query);
801 LOGE("Failed to get gum user list");
808 /* Make new user list */
811 while (iter != NULL) {
812 user = (GumUser*) iter->data;
813 g_object_get(G_OBJECT(user), "uid", &uid, NULL);
814 if (NULL != home_dir) {
818 g_object_get(G_OBJECT(user), "homedir", &home_dir, NULL);
819 g_object_get(G_OBJECT(user), "usertype", &gumut, NULL);
820 user_type = g_strdup(gum_user_type_to_string(gumut));
821 if (NULL == user_type) {
822 gum_user_service_list_free(users);
828 if (NULL != home_dir) {
829 g_dir_engine_info = (char*)calloc(strlen(home_dir) + 34, sizeof(char));
830 if (NULL == g_dir_engine_info) {
831 gum_user_service_list_free(users);
837 snprintf(g_dir_engine_info, strlen(home_dir) + 34, "%s/share/.voice/tts/1.0/engine-info", home_dir);
839 md_iter = g_list_first(list);
840 while (NULL != md_iter) {
841 md = (metadata *)md_iter->data;
842 LOGD(" - key(%s) value(%s)", md->key, md->value);
843 md_iter = g_list_next(md_iter);
846 if (0 != __remove_engine_info_xml(pkgid, user_type, uid)) {
847 LOGE("[ERROR] Fail to remove engine info file");
853 free(g_dir_engine_info);
854 g_dir_engine_info = NULL;
858 LOGD("Finish release memory");
859 iter = g_list_next(iter);
860 LOGD("Finish next iter");
862 iter = g_list_next(iter);
866 gum_user_service_list_free(users);
871 LOGD("[DEBUG] usertype: %s", g_user_type);
873 ret = tzplatform_set_user(g_uid);
875 LOGE("[ERROR] Invalid uid");
876 g_object_unref(g_guser);
881 LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
882 printf("[Parser Debug][DEBUG] TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
885 g_dir_engine_info = strdup(TTS_ENGINE_INFO);
886 if (NULL == g_dir_engine_info) {
887 LOGE("[ERROR] Fail to allocate memory");
888 g_object_unref(g_guser);
894 if (0 != __remove_engine_info_xml(pkgid, g_user_type, g_uid)) {
895 LOGE("[ERROR] Fail to remove engine info file");
900 if (NULL != g_guser) {
901 g_object_unref(g_guser);
906 if (NULL != g_dir_engine_info) {
907 free(g_dir_engine_info);
908 g_dir_engine_info = NULL;
916 int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
918 LOGD("METADATA UPGRADE");
919 LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
921 PKGMGR_MDPARSER_PLUGIN_UNINSTALL(pkgid, appid, list);
922 PKGMGR_MDPARSER_PLUGIN_INSTALL(pkgid, appid, list);