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_TAG_VOICE_BASE "tts-voice"
59 #define TTS_CONFIG_BASE tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice")
60 #define TTS_HOME tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/tts")
61 #define TTS_ENGINE_BASE tzplatform_mkpath(tzplatform_getid("TZ_USER_HOME"), "share/.voice/tts/1.0")
62 #define TTS_ENGINE_INFO tzplatform_mkpath(tzplatform_getid("TZ_USER_SHARE"), ".voice/tts/1.0/engine-info")
64 #define TTS_VOICE_INFO tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "voice/tts/1.0/tts-voice.xml")
66 #define TTS_GLOBAL_CONFIG_BASE "/etc/skel/share/.voice"
67 #define TTS_GLOBAL_HOME "/etc/skel/share/.voice/tts"
68 #define TTS_GLOBAL_ENGINE_BASE "/etc/skel/share/.voice/tts/1.0"
69 #define TTS_GLOBAL_ENGINE_INFO "/etc/skel/share/.voice/tts/1.0/engine-info"
71 #define TTS_METADATA_NAME "http://tizen.org/metadata/tts-engine/name"
72 #define TTS_METADATA_LANGUAGE "http://tizen.org/metadata/tts-engine/language"
73 #define TTS_METADATA_CREDENTIAL_REQUIRED "http://tizen.org/metadata/tts-engine/credential-required"
74 #define TTS_METADATA_SETTING "http://tizen.org/metadata/tts-engine/setting"
75 #define TTS_METADATA_TEXT_SIZE "http://tizen.org/metadata/tts-engine/text-size"
76 #define TTS_METADATA_PITCH_SUPPORT "http://tizen.org/metadata/tts-engine/pitch-support"
78 #define TTS_MAX_TEXT_SIZE "2000"
81 #define FREE(x) { if (NULL != x) { free(x); x = NULL; } }
82 #define G_FREE(x) { if (NULL != x) { g_free(x); x = NULL; } }
84 typedef struct metadata {
95 voice_info_s *voice_info;
99 static xmlDocPtr g_doc;
100 GumUser *g_guser = NULL;
101 uid_t g_uid = 301; // app_fw
102 gid_t g_gid = 301; // app_fw
103 GumUserType g_ut = GUM_USERTYPE_NONE;
104 gchar *g_user_type = NULL;
106 char *g_dir_config_base = NULL;
107 char *g_dir_home = NULL;
108 char *g_dir_engine_base = NULL;
109 char *g_dir_engine_info = NULL;
111 GSList *g_voice_info_list = NULL;
113 static int __create_engine_info_xml(const char *pkgid)
115 LOGD("@@@ Create engine info doc");
116 g_doc = xmlNewDoc((xmlChar*)"1.0");
118 LOGE("[ERROR] Fail to new doc");
125 static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid, gid_t gid)
127 LOGD("@@@ Save engine info doc");
128 char *dir_config_base = NULL;
129 char *dir_home = NULL;
130 char *dir_engine_base = NULL;
131 char *dir_engine_info = NULL;
133 if (NULL == ut || (NULL != ut && 0 == strcmp(ut, "none"))) {
134 LOGE("[ERROR] Usertype is NONE");
138 uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
142 LOGD("uid(%d)", uid);
144 if (globalapp_uid == uid) {
146 dir_config_base = strdup(TTS_GLOBAL_CONFIG_BASE);
147 dir_home = strdup(TTS_GLOBAL_HOME);
148 dir_engine_base = strdup(TTS_GLOBAL_ENGINE_BASE);
149 dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
150 tmp_uid = 301; // app_fw
151 tmp_gid = 301; // app_fw
153 /* User app, Guest app, Security app */
154 if (NULL != g_dir_config_base)
155 dir_config_base = strdup(g_dir_config_base);
156 if (NULL != g_dir_home)
157 dir_home = strdup(g_dir_home);
158 if (NULL != g_dir_engine_base)
159 dir_engine_base = strdup(g_dir_engine_base);
160 if (NULL != g_dir_engine_info)
161 dir_engine_info = strdup(g_dir_engine_info);
166 if (NULL == dir_config_base || NULL == dir_home || NULL == dir_engine_base || NULL == dir_engine_info) {
167 LOGE("[ERROR] Fail to allocate memory");
168 FREE(dir_config_base)
170 FREE(dir_engine_base)
171 FREE(dir_engine_info)
176 LOGD("[DEBUG] dir_engine_info(%s)", dir_engine_info);
179 /* Make directories */
181 // if (0 != access(dir_config_base, F_OK)) {
182 fd = open(dir_config_base, O_DIRECTORY);
184 LOGE("[INFO] No directory : %s, errno : %d", dir_config_base, errno);
185 if (0 != mkdir(dir_config_base, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
186 LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_config_base, errno);
187 FREE(dir_config_base)
189 FREE(dir_engine_base)
190 FREE(dir_engine_info)
193 LOGD("Success to make directory : %s", dir_config_base);
194 if (0 != chown(dir_config_base, tmp_uid, tmp_gid)) {
195 LOGD("[ERROR] Fail to change user and group, errno : %d", errno);
197 LOGD("[DEBUG] Success to change user and group");
204 // if (0 != access(dir_home, F_OK)) {
205 fd = open(dir_home, O_DIRECTORY);
207 LOGE("[INFO] No directory : %s, errno : %d", dir_home, errno);
208 if (0 != mkdir(dir_home, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
209 LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_home, errno);
210 FREE(dir_config_base)
212 FREE(dir_engine_base)
213 FREE(dir_engine_info)
216 LOGD("Success to make directory : %s", dir_home);
217 if (0 != chown(dir_home, tmp_uid, tmp_gid)) {
218 LOGD("[ERROR] Fail to change user and group, errno : %d", errno);
220 LOGD("[DEBUG] Success to change user and group");
227 // if (0 != access(dir_engine_base, F_OK)) {
228 fd = open(dir_engine_base, O_DIRECTORY);
230 LOGE("[INFO] No directory : %s, errno : %d", dir_engine_base, errno);
231 if (0 != mkdir(dir_engine_base, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
232 LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_engine_base, errno);
233 FREE(dir_config_base)
235 FREE(dir_engine_base)
236 FREE(dir_engine_info)
239 LOGD("Success to make directory : %s", dir_engine_base);
240 if (0 != chown(dir_engine_base, tmp_uid, tmp_gid)) {
241 LOGD("[ERROR] Fail to change user and group, errno : %d", errno);
243 LOGD("[DEBUG] Success to change user and group");
250 // if (0 != access(dir_engine_info, F_OK)) {
251 fd = open(dir_engine_info, O_DIRECTORY);
253 LOGE("[INFO] No directory : %s, errno : %d", dir_engine_info, errno);
254 if (0 != mkdir(dir_engine_info, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
255 LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_engine_info, errno);
256 FREE(dir_config_base)
258 FREE(dir_engine_base)
259 FREE(dir_engine_info)
262 LOGD("Success to make directory : %s", dir_engine_info);
263 if (0 != chown(dir_engine_info, tmp_uid, tmp_gid)) {
264 LOGD("[ERROR] Fail to change user and group, errno : %d", errno);
266 LOGD("[DEBUG] Success to change user and group");
274 char path[256] = {'\0',};
275 snprintf(path, 256, "%s/%s.xml", dir_engine_info, pkgid);
276 int ret = xmlSaveFormatFile(path, g_doc, 1);
277 LOGD("xmlSaveFile (%d)", ret);
279 if (0 != chown(path, tmp_uid, tmp_gid)) {
280 LOGD("[ERROR] Fail to change user and group");
282 LOGD("[DEBUG] Success to change user and group");
286 FREE(dir_config_base)
288 FREE(dir_engine_base)
289 FREE(dir_engine_info)
295 static int __remove_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid)
297 LOGD("@@@ Remove engine info doc");
299 char *dir_engine_info = NULL;
301 if (NULL == ut || (NULL != ut && 0 == strcmp(ut, "none"))) {
302 LOGE("[ERROR] Usertype is NONE");
306 uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
308 LOGD("uid(%d)", uid);
310 if (globalapp_uid == uid) {
312 dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
314 /* User app, Guest app, Security app */
315 if (NULL != g_dir_engine_info)
316 dir_engine_info = strdup(g_dir_engine_info);
319 if (NULL == dir_engine_info) {
320 LOGE("[ERROR] Fail to allocate memory");
324 LOGD("[DEBUG] dir_engine_info(%s)", dir_engine_info);
327 char path[256] = {'\0',};
328 snprintf(path, 256, "%s/%s.xml", dir_engine_info, pkgid);
329 if (0 == access(path, F_OK)) {
330 LOGD("Remove engine info xml(%s)", path);
331 if (0 != remove(path)) {
332 LOGE("[ERROR] Fail to Remove engine info xml(%s)", path);
336 FREE(dir_engine_info)
342 static void __insert_language_from_metadata(xmlNodePtr root, const char *language)
344 LOGD("@@@ Insert language");
348 if (NULL == root || NULL == language) {
349 LOGE("Invalid parameter, root(%p), language(%s)", root, language);
353 char *tmp_lang = NULL;
354 char *tmp_free = NULL;
355 tmp_free = tmp_lang = strdup(language);
356 if (NULL == tmp_lang) {
357 LOGE("Fail to memory allocation");
360 xmlNodePtr voices_node = NULL;
361 xmlNodePtr voice_node = NULL;
363 voices_node = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_VOICE_SET);
365 voice = strsep(&tmp_lang, ",");
366 while (NULL != voice) {
367 LOGD("voice (%s)", voice);
368 voice_node = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_VOICE);
369 lang = strsep(&voice, ":");
370 LOGD("lang (%s)", lang);
371 type = strsep(&voice, " ");
372 LOGD("type (%s)", type);
373 xmlSetProp(voice_node, (const xmlChar*)TTS_TAG_ENGINE_VOICE_TYPE, (const xmlChar*)type);
374 xmlNodeSetContent(voice_node, (const xmlChar*)lang);
375 xmlAddChild(voices_node, voice_node);
376 voice = strsep(&tmp_lang, ",");
379 /* add extra voices */
380 LOGD("Add extra voices");
381 if (NULL != g_voice_info_list) {
383 voice_info_s *extra_voice = NULL;
384 for (iter = g_voice_info_list ; iter != NULL ; iter = g_slist_next(iter)) {
385 extra_voice = (voice_info_s*)iter->data;
386 if (NULL != extra_voice) {
387 lang = strdup(extra_voice->lang);
388 type = strdup(extra_voice->type);
389 LOGD("lang(%s), type(%s)", lang, type);
392 voice_node = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_VOICE);
393 xmlSetProp(voice_node, (const xmlChar*)TTS_TAG_ENGINE_VOICE_TYPE, (const xmlChar*)type);
394 xmlNodeSetContent(voice_node, (const xmlChar*)lang);
395 xmlAddChild(voices_node, voice_node);
398 LOGD("Finish to add voice node");
406 LOGD("Memory release");
408 if (NULL != extra_voice->lang) {
409 free(extra_voice->lang);
411 if (NULL != extra_voice->type) {
412 free(extra_voice->type);
414 LOGD("Free extra_voice");
420 LOGD("Free voice info list");
421 g_slist_free(g_voice_info_list);
422 g_voice_info_list = NULL;
425 xmlAddChild(root, voices_node);
430 static int __get_voice_inxml()
432 xmlDocPtr doc = NULL;
433 xmlNodePtr cur = NULL;
435 LOGD("TTS voice info xml (%s)", TTS_VOICE_INFO);
437 if (0 != access(TTS_VOICE_INFO, F_OK)) {
438 LOGD("There is no extra voice info.");
441 doc = xmlParseFile(TTS_VOICE_INFO);
443 LOGE("Fail to parse file");
447 cur = xmlDocGetRootElement(doc);
449 LOGE("Empty document");
454 if (xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_VOICE_BASE)) {
455 LOGE("root node is NOT %s", TTS_TAG_VOICE_BASE);
460 cur = cur->xmlChildrenNode;
462 LOGE("<tts-voice> child NULL");
467 xmlChar *attr = NULL;
472 while (NULL != cur) {
473 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE_SET)) {
475 xmlNodePtr voice_node = NULL;
476 voice_node = cur->xmlChildrenNode;
478 while (NULL != voice_node) {
479 if (0 == xmlStrcmp(voice_node->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE)) {
480 voice_info_s *voice_info = (voice_info_s *)calloc(1, sizeof(voice_info_s));
481 if (NULL == voice_info) {
482 LOGE("Fail to allocate memory");
487 LOGD("Get property and keys");
488 attr = xmlGetProp(voice_node, (const xmlChar *)TTS_TAG_ENGINE_VOICE_TYPE);
490 // strncpy(type, (char*)attr, strlen((char*)attr));
491 voice_info->type = strdup((char*)attr);
492 LOGD("type(%s)", voice_info->type);
496 LOGD("No voice type");
499 key = xmlNodeGetContent(voice_node);
501 // strncpy(lang, (char*)key, strlen((char*)key));
502 voice_info->lang = strdup((char*)key);
503 LOGD("lang(%s)", voice_info->lang);
507 LOGD("No voice info");
510 g_voice_info_list = g_slist_append(g_voice_info_list, voice_info);
513 voice_node = voice_node->next;
516 LOGD("Unknown tag (%s)", (const char*)cur->name);
528 static int __write_metadata_inxml(const char *pkgid, const char *appid, GList *list)
533 bool isTextsize = false;
535 __create_engine_info_xml(pkgid);
537 xmlNodePtr root = NULL;
538 xmlNodePtr cur = NULL;
540 root = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_BASE);
542 LOGE("[ERROR] Fail to get new node");
543 // xmlFreeDoc(g_doc);
546 xmlDocSetRootElement(g_doc, root);
549 // cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_NAME);
550 // xmlNodeSetContent(cur, (const xmlChar*)pkgid);
551 // xmlAddChild(root, cur);
554 iter = g_list_first(list);
555 while (NULL != iter) {
556 md = (metadata *)iter->data;
557 if (NULL != md && NULL != md->key) {
558 LOGD(" - key(%s) value(%s)", md->key, md->value);
559 if (!strcmp(md->key, TTS_METADATA_LANGUAGE)) {
561 __insert_language_from_metadata(root, md->value);
562 } else if (!strcmp(md->key, TTS_METADATA_CREDENTIAL_REQUIRED)) {
563 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_CREDENTIAL);
564 xmlNodeSetContent(cur, (const xmlChar*)md->value);
565 xmlAddChild(root, cur);
566 } else if (!strcmp(md->key, TTS_METADATA_SETTING)) {
567 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_SETTING);
568 xmlNodeSetContent(cur, (const xmlChar*)md->value);
569 xmlAddChild(root, cur);
570 } else if (!strcmp(md->key, TTS_METADATA_NAME)) {
571 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_NAME);
572 xmlNodeSetContent(cur, (const xmlChar*)md->value);
573 xmlAddChild(root, cur);
574 } else if (!strcmp(md->key, TTS_METADATA_TEXT_SIZE)) {
575 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_TEXT_SIZE);
576 xmlNodeSetContent(cur, (const xmlChar*)md->value);
577 xmlAddChild(root, cur);
579 } else if (!strcmp(md->key, TTS_METADATA_PITCH_SUPPORT)) {
580 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_PITCH_SUPPORT);
581 xmlNodeSetContent(cur, (const xmlChar*)md->value);
582 xmlAddChild(root, cur);
584 LOGW("[WARNING] Unknown metadata type");
587 iter = g_list_next(iter);
590 if (false == isTextsize) {
591 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_TEXT_SIZE);
592 xmlNodeSetContent(cur, (const xmlChar*)TTS_MAX_TEXT_SIZE);
593 xmlAddChild(root, cur);
594 LOGD("[DEBUG] Max text size is set as %s.", TTS_MAX_TEXT_SIZE);
597 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_ID);
598 xmlNodeSetContent(cur, (const xmlChar*)pkgid);
599 xmlAddChild(root, cur);
608 int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
610 LOGD("METADATA INSTALL");
611 LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
614 ret = pkgmgr_installer_info_get_target_uid(&g_uid);
616 LOGE("[ERROR] Fail to get target uid");
619 LOGD("uid(%d)", g_uid);
620 printf("[Parser Debug][DEBUG] uid(%d)", g_uid);
623 uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
624 if (globalapp_uid == g_uid) {
625 g_user_type = g_strdup("admin");
627 g_guser = gum_user_get_sync(g_uid, FALSE);
628 if (NULL == g_guser) {
629 LOGE("[ERROR] g_guser is NULL");
633 g_object_get(G_OBJECT(g_guser), "gid", &g_gid, NULL);
634 g_object_get(G_OBJECT(g_guser), "usertype", &g_ut, NULL);
635 g_user_type = g_strdup(gum_user_type_to_string(g_ut));
638 if (NULL == g_user_type) {
639 LOGE("[ERROR] Fail to allocate memory");
640 if (NULL != g_guser) {
641 g_object_unref(g_guser);
647 if (0 == strcmp(g_user_type, "none")) {
648 /* GUM_USERTYPE_NONE */
649 LOGE("[ERROR] Fail to get target uid");
650 g_object_unref(g_guser);
656 if (globalapp_uid == g_uid) {
657 /* global directory */
658 LOGD("[DEBUG] usertype: %s", g_user_type);
659 if (0 >= g_list_length(list)) {
660 LOGE("[ERROR] No Engine Metadata");
665 if (0 != __write_metadata_inxml(pkgid, appid, list)) {
666 LOGE("[ERROR] Fail to write metadata in the xml");
672 /* Save in /etc/skel/share/ */
673 g_dir_config_base = strdup(TTS_GLOBAL_CONFIG_BASE);
674 g_dir_home = strdup(TTS_GLOBAL_HOME);
675 g_dir_engine_base = strdup(TTS_GLOBAL_ENGINE_BASE);
676 g_dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
678 if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) {
679 LOGE("[ERROR] Fail to allocate memory");
680 FREE(g_dir_config_base)
682 FREE(g_dir_engine_base)
683 FREE(g_dir_engine_info)
690 if (0 != __save_engine_info_xml(pkgid, g_user_type, g_uid, g_gid)) {
691 LOGE("[ERROR] Fail to make engine info file");
697 /* Get user data by using libgum */
699 GumUserService *gus = NULL;
700 GumUserList *users = NULL;
701 GumUserList *iter = NULL;
702 GumUser *user = NULL;
704 GumUserType gumut = GUM_USERTYPE_NONE;
705 gchar *user_type = NULL;
709 gchar *home_dir = NULL;
711 gus = gum_user_service_create_sync(TRUE);
713 LOGE("Failed to create gum user service");
718 query = g_strsplit("admin,normal", ",", -1);
720 users = gum_user_service_get_user_list_sync(gus, (const gchar *const *)query);
731 /* Make new user list */
734 while (iter != NULL) {
735 user = (GumUser*) iter->data;
736 g_object_get(G_OBJECT(user), "uid", &uid, NULL);
739 g_object_get(G_OBJECT(user), "gid", &gid, NULL);
740 g_object_get(G_OBJECT(user), "homedir", &home_dir, NULL);
741 g_object_get(G_OBJECT(user), "usertype", &gumut, NULL);
742 user_type = g_strdup(gum_user_type_to_string(gumut));
743 if (NULL == user_type) {
744 gum_user_service_list_free(users);
751 LOGD("[DEBUG] user info");
752 if (NULL != home_dir) {
753 LOGD("[DEBUG] uid(%d), gid(%d), user_type(%s), home_dir(%s)", uid, gid, user_type, home_dir);
755 g_dir_config_base = (char*)calloc(strlen(home_dir) + 14, sizeof(char));
756 g_dir_home = (char*)calloc(strlen(home_dir) + 18, sizeof(char));
757 g_dir_engine_base = (char*)calloc(strlen(home_dir) + 22, sizeof(char));
758 g_dir_engine_info = (char*)calloc(strlen(home_dir) + 34, sizeof(char));
760 if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) {
761 LOGE("[ERROR] Fail to allocate memory");
762 FREE(g_dir_config_base)
764 FREE(g_dir_engine_base)
765 FREE(g_dir_engine_info)
766 gum_user_service_list_free(users);
773 snprintf(g_dir_config_base, strlen(home_dir) + 14, "%s/share/.voice", home_dir);
774 snprintf(g_dir_home, strlen(home_dir) + 18, "%s/share/.voice/tts", home_dir);
775 snprintf(g_dir_engine_base, strlen(home_dir) + 22, "%s/share/.voice/tts/1.0", home_dir);
776 snprintf(g_dir_engine_info, strlen(home_dir) + 34, "%s/share/.voice/tts/1.0/engine-info", home_dir);
778 LOGD("[DEBUG] g_dir_engine_info(%s)", g_dir_engine_info);
780 if (0 != __save_engine_info_xml(pkgid, user_type, uid, gid)) {
781 LOGE("[ERROR] Fail to make engine info file");
784 FREE(g_dir_config_base)
786 FREE(g_dir_engine_base)
787 FREE(g_dir_engine_info)
793 iter = g_list_next(iter);
796 gum_user_service_list_free(users);
801 LOGD("[DEBUG] usertype: %s", g_user_type);
803 ret = tzplatform_set_user(g_uid);
805 LOGE("[ERROR] Invalid uid");
806 g_object_unref(g_guser);
811 LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
812 printf("[Parser Debug][DEBUG] TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
815 if (0 >= g_list_length(list)) {
816 LOGE("[ERROR] No Engine Metadata");
817 g_object_unref(g_guser);
823 if (0 != __write_metadata_inxml(pkgid, appid, list)) {
824 LOGE("[ERROR] Fail to write metadata in the xml");
826 g_object_unref(g_guser);
832 g_dir_config_base = strdup(TTS_CONFIG_BASE);
833 g_dir_home = strdup(TTS_HOME);
834 g_dir_engine_base = strdup(TTS_ENGINE_BASE);
835 g_dir_engine_info = strdup(TTS_ENGINE_INFO);
837 if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) {
838 LOGE("[ERROR] Fail to allocate memory");
839 FREE(g_dir_config_base)
841 FREE(g_dir_engine_base)
842 FREE(g_dir_engine_info)
844 g_object_unref(g_guser);
850 if (0 != __save_engine_info_xml(pkgid, g_user_type, g_uid, g_gid)) {
851 LOGE("[ERROR] Fail to make engine info file");
853 if (NULL != g_guser) {
854 g_object_unref(g_guser);
863 if (NULL != g_guser) {
864 g_object_unref(g_guser);
869 FREE(g_dir_config_base)
871 FREE(g_dir_engine_base)
872 FREE(g_dir_engine_info)
878 int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
880 LOGD("METADATA UNINSTALL");
881 LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
884 ret = pkgmgr_installer_info_get_target_uid(&g_uid);
886 LOGE("[ERROR] Fail to get target uid");
889 LOGD("uid(%d)", g_uid);
890 printf("[Parser Debug][DEBUG] uid(%d)", g_uid);
893 uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
894 if (globalapp_uid == g_uid) {
895 g_user_type = g_strdup("admin");
896 LOGD("[DEBUG] g_user_type: %s (%d)", g_user_type, globalapp_uid);
898 g_guser = gum_user_get_sync(g_uid, FALSE);
899 if (NULL == g_guser) {
900 LOGE("[ERROR] g_guser is NULL");
904 g_object_get(G_OBJECT(g_guser), "usertype", &g_ut, NULL);
905 g_user_type = g_strdup(gum_user_type_to_string(g_ut));
907 LOGD("[DEBUG] g_user_type: %s (%d)", g_user_type, globalapp_uid);
910 if (NULL == g_user_type) {
911 LOGE("[ERROR] Fail to allocate memory");
912 if (NULL != g_guser) {
913 g_object_unref(g_guser);
919 if (0 == strcmp(g_user_type, "none")) {
920 /* GUM_USERTYPE_NONE */
921 LOGE("[ERROR] Fail to get target uid");
922 g_object_unref(g_guser);
928 if (globalapp_uid == g_uid) {
929 /* global directory */
930 LOGD("[DEBUG] usertype: %s", g_user_type);
932 /* Remove files in /etc/skel/share/ */
933 g_dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
934 if (NULL == g_dir_engine_info) {
935 LOGE("[ERROR] Fail to allocate memory");
940 if (0 != __remove_engine_info_xml(pkgid, g_user_type, g_uid)) {
941 LOGE("[ERROR] Fail to remove engine info file");
944 /* Get user data by using libgum */
946 GumUserService *gus = NULL;
947 GumUserList *users = NULL;
948 GumUserList *iter = NULL;
949 GumUser *user = NULL;
951 GumUserType gumut = GUM_USERTYPE_NONE;
952 gchar *user_type = NULL;
955 gchar *home_dir = NULL;
957 GList *md_iter = NULL;
960 gus = gum_user_service_create_sync(TRUE);
962 LOGE("Failed to create gum user service");
967 query = g_strsplit("admin,normal", ",", -1);
969 users = gum_user_service_get_user_list_sync(gus, (const gchar *const *)query);
980 /* Make new user list */
983 while (iter != NULL) {
984 user = (GumUser*) iter->data;
985 g_object_get(G_OBJECT(user), "uid", &uid, NULL);
987 g_object_get(G_OBJECT(user), "homedir", &home_dir, NULL);
988 g_object_get(G_OBJECT(user), "usertype", &gumut, NULL);
989 user_type = g_strdup(gum_user_type_to_string(gumut));
990 if (NULL == user_type) {
991 gum_user_service_list_free(users);
998 if (NULL != home_dir) {
999 g_dir_engine_info = (char*)calloc(strlen(home_dir) + 34, sizeof(char));
1000 if (NULL == g_dir_engine_info) {
1001 gum_user_service_list_free(users);
1003 g_object_unref(gus);
1009 snprintf(g_dir_engine_info, strlen(home_dir) + 34, "%s/share/.voice/tts/1.0/engine-info", home_dir);
1011 md_iter = g_list_first(list);
1012 while (NULL != md_iter) {
1013 md = (metadata *)md_iter->data;
1014 LOGD(" - key(%s) value(%s)", md->key, md->value);
1015 md_iter = g_list_next(md_iter);
1018 if (0 != __remove_engine_info_xml(pkgid, user_type, uid)) {
1019 LOGE("[ERROR] Fail to remove engine info file");
1023 FREE(g_dir_engine_info)
1027 LOGD("Finish release memory");
1028 iter = g_list_next(iter);
1029 LOGD("Finish next iter");
1032 gum_user_service_list_free(users);
1033 g_object_unref(gus);
1036 /* user directory */
1037 LOGD("[DEBUG] usertype: %s", g_user_type);
1039 ret = tzplatform_set_user(g_uid);
1041 LOGE("[ERROR] Invalid uid");
1042 g_object_unref(g_guser);
1047 LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
1048 printf("[Parser Debug][DEBUG] TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
1051 g_dir_engine_info = strdup(TTS_ENGINE_INFO);
1052 if (NULL == g_dir_engine_info) {
1053 LOGE("[ERROR] Fail to allocate memory");
1054 g_object_unref(g_guser);
1060 if (0 != __remove_engine_info_xml(pkgid, g_user_type, g_uid)) {
1061 LOGE("[ERROR] Fail to remove engine info file");
1066 if (NULL != g_guser) {
1067 g_object_unref(g_guser);
1072 FREE(g_dir_engine_info)
1079 int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
1081 LOGD("METADATA UPGRADE");
1082 LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
1084 PKGMGR_MDPARSER_PLUGIN_UNINSTALL(pkgid, appid, list);
1085 PKGMGR_MDPARSER_PLUGIN_INSTALL(pkgid, appid, list);