Update version (1.90.9)
[platform/core/uifw/tts.git] / engine-parser / src / tts-engine-parser.c
1 //
2 // Copyright (c) 2016 Samsung Electronics Co., Ltd.
3 //
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
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
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.
15 //
16
17 #include <app_manager.h>
18 #include <dlog.h>
19 #include <errno.h>
20 #include <glib.h>
21 #include <libxml/parser.h>
22 #include <libxml/tree.h>
23 #include <pkgmgr-info.h>
24 #include <pkgmgr_installer_info.h>
25 #include <stdio.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <fcntl.h>
29 #include <tzplatform_config.h>
30
31 #include <gum/gum-user.h>
32 #include <gum/gum-user-service.h>
33 #include <gum/common/gum-user-types.h>
34
35 /* Define EXPORT_API */
36 #ifndef EXPORT_API
37 #define EXPORT_API __attribute__((visibility("default")))
38 #endif
39
40 #ifdef LOG_TAG
41 #undef LOG_TAG
42 #endif
43 #define LOG_TAG "tts-engine-parser"
44
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"
54 #define TTS_TAG_ENGINE_TEXT_SIZE                "text-size"
55
56 #define TTS_TAG_VOICE_BASE                      "tts-voice"
57
58 #define TTS_VOICE_INFO  tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "voice/tts/1.0/tts-voice.xml")
59
60 #define TTS_GLOBAL_CONFIG_BASE          tzplatform_mkpath(tzplatform_getid("TZ_SYS_GLOBALUSER_DATA"), ".voice")
61 #define TTS_GLOBAL_HOME         tzplatform_mkpath(tzplatform_getid("TZ_SYS_GLOBALUSER_DATA"), ".voice/tts")
62 #define TTS_GLOBAL_ENGINE_INFO          tzplatform_mkpath(tzplatform_getid("TZ_SYS_GLOBALUSER_DATA"), ".voice/tts/engine-info")
63
64
65 #define TTS_METADATA_NAME                       "http://tizen.org/metadata/tts-engine/name"
66 #define TTS_METADATA_LANGUAGE                   "http://tizen.org/metadata/tts-engine/language"
67 #define TTS_METADATA_CREDENTIAL_REQUIRED        "http://tizen.org/metadata/tts-engine/credential-required"
68 #define TTS_METADATA_SETTING            "http://tizen.org/metadata/tts-engine/setting"
69 #define TTS_METADATA_TEXT_SIZE          "http://tizen.org/metadata/tts-engine/text-size"
70 #define TTS_METADATA_PITCH_SUPPORT      "http://tizen.org/metadata/tts-engine/pitch-support"
71
72 #define TTS_MAX_TEXT_SIZE       "2000"
73
74 /* Define Macro */
75 #define FREE(x) { if (NULL != x)        { free(x);      x = NULL; } }
76 #define G_FREE(x)       { if (NULL != x) { g_free(x);   x = NULL; } }
77
78 typedef struct metadata {
79         const char *key;
80         const char *value;
81 } metadata;
82
83 typedef struct {
84         char *lang;
85         char *type;
86 } voice_info_s;
87
88 typedef struct {
89         voice_info_s *voice_info;
90         int size;
91 } voice_info_list_s;
92
93 static xmlDocPtr g_doc;
94 static GumUser *g_guser = NULL;
95 static uid_t g_uid = 301;       // app_fw
96 static gid_t g_gid = 301;       // app_fw
97 static gchar *g_user_type = NULL;
98
99 static char *g_dir_config_base = NULL;
100 static char *g_dir_home = NULL;
101 static char *g_dir_engine_info = NULL;
102
103 static GSList *g_voice_info_list = NULL;
104
105 static int __create_engine_info_xml(const char *pkgid)
106 {
107         LOGD("@@@ Create engine info doc");
108         g_doc = xmlNewDoc((xmlChar*)"1.0");
109         if (NULL == g_doc) {
110                 LOGE("[ERROR] Fail to new doc");
111                 return -1;
112         }
113         LOGD("@@@");
114         return 0;
115 }
116
117 static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid, gid_t gid)
118 {
119         LOGD("@@@ Save engine info doc");
120         char *dir_config_base = NULL;
121         char *dir_home = NULL;
122         char *dir_engine_info = NULL;
123
124         if (NULL == ut || (NULL != ut && 0 == strcmp(ut, "none"))) {
125                 LOGE("[ERROR] Usertype is NONE");
126                 return -1;
127         }
128
129         uid_t tmp_uid = 0;
130         gid_t tmp_gid = 0;
131
132         LOGD("uid(%u)", uid);
133
134         dir_config_base = strdup(TTS_GLOBAL_CONFIG_BASE);
135         dir_home = strdup(TTS_GLOBAL_HOME);
136         dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
137         tmp_uid = 301;  // app_fw
138         tmp_gid = 301;  // app_fw
139
140
141         if (NULL == dir_config_base || NULL == dir_home || NULL == dir_engine_info) {
142                 LOGE("[ERROR] Fail to allocate memory");
143                 FREE(dir_config_base)
144                 FREE(dir_home)
145                 FREE(dir_engine_info)
146
147                 return -1;
148         }
149
150         LOGD("[DEBUG] dir_engine_info(%s)", dir_engine_info);
151
152
153         /* Make directories */
154         int fd = -1;
155 //      if (0 != access(dir_config_base, F_OK)) {
156         fd = open(dir_config_base, O_DIRECTORY);
157         if (-1 == fd) {
158                 LOGE("[INFO] No directory : %s, errno : %d", dir_config_base, errno);
159                 if (0 != mkdir(dir_config_base, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
160                         LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_config_base, errno);
161                         FREE(dir_config_base)
162                         FREE(dir_home)
163                         FREE(dir_engine_info)
164                         return -1;
165                 } else {
166                         LOGD("Success to make directory : %s", dir_config_base);
167                         if (0 != chown(dir_config_base, tmp_uid, tmp_gid)) {
168                                 LOGD("[ERROR] Fail to change user and group, errno : %d", errno);
169                         } else {
170                                 LOGD("[DEBUG] Success to change user and group");
171                         }
172                 }
173         } else {
174                 close(fd);
175         }
176
177 //      if (0 != access(dir_home, F_OK)) {
178         fd = open(dir_home, O_DIRECTORY);
179         if (-1 == fd) {
180                 LOGE("[INFO] No directory : %s, errno : %d", dir_home, errno);
181                 if (0 != mkdir(dir_home, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
182                         LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_home, errno);
183                         FREE(dir_config_base)
184                         FREE(dir_home)
185                         FREE(dir_engine_info)
186                         return -1;
187                 } else {
188                         LOGD("Success to make directory : %s", dir_home);
189                         if (0 != chown(dir_home, tmp_uid, tmp_gid)) {
190                                 LOGD("[ERROR] Fail to change user and group, errno : %d", errno);
191                         } else {
192                                 LOGD("[DEBUG] Success to change user and group");
193                         }
194                 }
195         } else {
196                 close(fd);
197         }
198
199 //      if (0 != access(dir_engine_info, F_OK)) {
200         fd = open(dir_engine_info, O_DIRECTORY);
201         if (-1 == fd) {
202                 LOGE("[INFO] No directory : %s, errno : %d", dir_engine_info, errno);
203                 if (0 != mkdir(dir_engine_info, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
204                         LOGE("[ERROR] Fail to make directory : %s, errno : %d", dir_engine_info, errno);
205                         FREE(dir_config_base)
206                         FREE(dir_home)
207                         FREE(dir_engine_info)
208                         return -1;
209                 } else {
210                         LOGD("Success to make directory : %s", dir_engine_info);
211                         if (0 != chown(dir_engine_info, tmp_uid, tmp_gid)) {
212                                 LOGD("[ERROR] Fail to change user and group, errno : %d", errno);
213                         } else {
214                                 LOGD("[DEBUG] Success to change user and group");
215                         }
216                 }
217         } else {
218                 close(fd);
219         }
220
221
222         char path[256] = {'\0',};
223         snprintf(path, 256, "%s/%s.xml", dir_engine_info, pkgid);
224         int ret = xmlSaveFormatFile(path, g_doc, 1);
225         LOGD("xmlSaveFile (%d)", ret);
226         if (0 == ret) {
227                 if (0 != chown(path, tmp_uid, tmp_gid)) {
228                         LOGD("[ERROR] Fail to change user and group");
229                 } else {
230                         LOGD("[DEBUG] Success to change user and group");
231                 }
232         }
233
234         FREE(dir_config_base)
235         FREE(dir_home)
236         FREE(dir_engine_info)
237
238         LOGD("@@@");
239         return 0;
240 }
241
242 static int __remove_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid)
243 {
244         LOGD("@@@ Remove engine info doc");
245
246         char *dir_engine_info = NULL;
247
248         if (NULL == ut || (NULL != ut && 0 == strcmp(ut, "none"))) {
249                 LOGE("[ERROR] Usertype is NONE");
250                 return -1;
251         }
252
253         // uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
254
255         LOGD("uid(%u)", uid);
256
257         dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
258
259         if (NULL == dir_engine_info) {
260                 LOGE("[ERROR] Fail to allocate memory");
261                 return -1;
262         }
263
264         LOGD("[DEBUG] dir_engine_info(%s)", dir_engine_info);
265
266
267         char path[256] = {'\0',};
268         snprintf(path, 256, "%s/%s.xml", dir_engine_info, pkgid);
269         LOGD("Remove engine info xml(%s)", path);
270         if (0 != remove(path)) {
271                 LOGE("[ERROR] Fail to Remove engine info xml(%s)", path);
272         }
273
274         FREE(dir_engine_info)
275
276         LOGD("@@@");
277         return 0;
278 }
279
280 static void __insert_language_from_metadata(xmlNodePtr root, const char *language)
281 {
282         LOGD("@@@ Insert language");
283         char* voice = NULL;
284         char* lang = NULL;
285         char* type = NULL;
286         if (NULL == root || NULL == language) {
287                 LOGE("Invalid parameter, root(%p), language(%s)", root, language);
288                 return;
289         }
290
291         char *tmp_lang = NULL;
292         char *tmp_free = NULL;
293         tmp_free = tmp_lang = strdup(language);
294         if (NULL == tmp_lang) {
295                 LOGE("Fail to memory allocation");
296                 return;
297         }
298         xmlNodePtr voices_node = NULL;
299         xmlNodePtr voice_node = NULL;
300
301         voices_node = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_VOICE_SET);
302
303         voice = strsep(&tmp_lang, ",");
304         while (NULL != voice) {
305                 LOGD("voice (%s)", voice);
306                 voice_node = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_VOICE);
307                 lang = strsep(&voice, ":");
308                 LOGD("lang (%s)", lang);
309                 type = strsep(&voice, " ");
310                 LOGD("type (%s)", type);
311                 xmlSetProp(voice_node, (const xmlChar*)TTS_TAG_ENGINE_VOICE_TYPE, (const xmlChar*)type);
312                 xmlNodeSetContent(voice_node, (const xmlChar*)lang);
313                 xmlAddChild(voices_node, voice_node);
314                 voice = strsep(&tmp_lang, ",");
315         }
316
317         /* add extra voices */
318         LOGD("Add extra voices");
319         if (NULL != g_voice_info_list) {
320                 GSList *iter;
321                 for (iter = g_voice_info_list ; iter != NULL ; iter = g_slist_next(iter)) {
322                         voice_info_s *extra_voice = (voice_info_s*)iter->data;
323                         if (NULL != extra_voice) {
324                                 lang = strdup(extra_voice->lang);
325                                 type = strdup(extra_voice->type);
326                                 LOGD("lang(%s), type(%s)", lang, type);
327
328                                 if (NULL != lang) {
329                                         voice_node = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_VOICE);
330                                         xmlSetProp(voice_node, (const xmlChar*)TTS_TAG_ENGINE_VOICE_TYPE, (const xmlChar*)type);
331                                         xmlNodeSetContent(voice_node, (const xmlChar*)lang);
332                                         xmlAddChild(voices_node, voice_node);
333                                 }
334
335                                 LOGD("Finish to add voice node");
336
337                                 if (NULL != lang) {
338                                         free(lang);
339                                 }
340                                 if (NULL != type) {
341                                         free(type);
342                                 }
343                                 LOGD("Memory release");
344
345                                 if (NULL != extra_voice->lang) {
346                                         free(extra_voice->lang);
347                                 }
348                                 if (NULL != extra_voice->type) {
349                                         free(extra_voice->type);
350                                 }
351                                 LOGD("Free extra_voice");
352                                 free(extra_voice);
353                                 extra_voice = NULL;
354                         }
355                 }
356
357                 LOGD("Free voice info list");
358                 g_slist_free(g_voice_info_list);
359                 g_voice_info_list = NULL;
360         }
361
362         xmlAddChild(root, voices_node);
363
364         FREE(tmp_free)
365 }
366
367 static int __get_voice_inxml()
368 {
369         xmlDocPtr doc = NULL;
370         xmlNodePtr cur = NULL;
371
372         LOGD("TTS voice info xml (%s)", TTS_VOICE_INFO);
373
374         if (0 != access(TTS_VOICE_INFO, F_OK)) {
375                 LOGD("There is no extra voice info.");
376                 return 0;
377         } else {
378                 doc = xmlParseFile(TTS_VOICE_INFO);
379                 if (NULL == doc) {
380                         LOGE("Fail to parse file");
381                         return -1;
382                 }
383
384                 cur = xmlDocGetRootElement(doc);
385                 if (NULL == cur) {
386                         LOGE("Empty document");
387                         xmlFreeDoc(doc);
388                         return -1;
389                 }
390
391                 if (xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_VOICE_BASE)) {
392                         LOGE("root node is NOT %s", TTS_TAG_VOICE_BASE);
393                         xmlFreeDoc(doc);
394                         return -1;
395                 }
396
397                 cur = cur->xmlChildrenNode;
398                 if (NULL == cur) {
399                         LOGE("<tts-voice> child NULL");
400                         xmlFreeDoc(doc);
401                         return -1;
402                 }
403
404 //              char lang[16];
405 //              char type[16];
406
407                 while (NULL != cur) {
408                         if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE_SET)) {
409                                 LOGD("<voices>");
410                                 xmlNodePtr voice_node = NULL;
411                                 voice_node = cur->xmlChildrenNode;
412
413                                 while (NULL != voice_node) {
414                                         if (0 == xmlStrcmp(voice_node->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE)) {
415                                                 voice_info_s *voice_info = (voice_info_s *)calloc(1, sizeof(voice_info_s));
416                                                 if (NULL == voice_info) {
417                                                         LOGE("Fail to allocate memory");
418                                                         xmlFreeDoc(doc);
419                                                         return -1;
420                                                 }
421
422                                                 LOGD("Get property and keys");
423                                                 xmlChar *attr = xmlGetProp(voice_node, (const xmlChar *)TTS_TAG_ENGINE_VOICE_TYPE);
424                                                 if (NULL != attr) {
425 //                                                      strncpy(type, (char*)attr, strlen((char*)attr));
426                                                         voice_info->type = strdup((char*)attr);
427                                                         LOGD("type(%s)", voice_info->type);
428                                                         xmlFree(attr);
429                                                         attr = NULL;
430                                                 } else {
431                                                         LOGD("No voice type");
432                                                 }
433
434                                                 xmlChar *key = xmlNodeGetContent(voice_node);
435                                                 if (NULL != key) {
436 //                                                      strncpy(lang, (char*)key, strlen((char*)key));
437                                                         voice_info->lang = strdup((char*)key);
438                                                         LOGD("lang(%s)", voice_info->lang);
439                                                         xmlFree(key);
440                                                         key = NULL;
441                                                 } else {
442                                                         LOGD("No voice info");
443                                                 }
444
445                                                 g_voice_info_list = g_slist_append(g_voice_info_list, voice_info);
446                                         }
447
448                                         voice_node = voice_node->next;
449                                 }
450                         } else {
451                                 LOGD("Unknown tag (%s)", (const char*)cur->name);
452                         }
453
454                         cur = cur->next;
455                 }
456
457                 xmlFreeDoc(doc);
458         }
459
460         return 0;
461 }
462
463 static int __write_metadata_inxml(const char *pkgid, const char *appid, GList *list)
464 {
465         GList *iter = NULL;
466         metadata *md = NULL;
467
468         bool isTextsize = false;
469
470         __create_engine_info_xml(pkgid);
471
472         xmlNodePtr root = NULL;
473         xmlNodePtr cur = NULL;
474
475         root = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_BASE);
476         if (NULL == root) {
477                 LOGE("[ERROR] Fail to get new node");
478 //              xmlFreeDoc(g_doc);
479                 return -1;
480         }
481         xmlDocSetRootElement(g_doc, root);
482
483         /* Save name */
484 //      cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_NAME);
485 //      xmlNodeSetContent(cur, (const xmlChar*)pkgid);
486 //      xmlAddChild(root, cur);
487
488
489         iter = g_list_first(list);
490         while (NULL != iter) {
491                 md = (metadata *)iter->data;
492                 if (NULL != md && NULL != md->key) {
493                         LOGD(" - key(%s) value(%s)", md->key, md->value);
494                         if (!strcmp(md->key, TTS_METADATA_LANGUAGE)) {
495                                 __get_voice_inxml();
496                                 __insert_language_from_metadata(root, md->value);
497                         } else if (!strcmp(md->key, TTS_METADATA_CREDENTIAL_REQUIRED)) {
498                                 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_CREDENTIAL);
499                                 xmlNodeSetContent(cur, (const xmlChar*)md->value);
500                                 xmlAddChild(root, cur);
501                         } else if (!strcmp(md->key, TTS_METADATA_SETTING)) {
502                                 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_SETTING);
503                                 xmlNodeSetContent(cur, (const xmlChar*)md->value);
504                                 xmlAddChild(root, cur);
505                         } else if (!strcmp(md->key, TTS_METADATA_NAME)) {
506                                 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_NAME);
507                                 xmlNodeSetContent(cur, (const xmlChar*)md->value);
508                                 xmlAddChild(root, cur);
509                         } else if (!strcmp(md->key, TTS_METADATA_TEXT_SIZE)) {
510                                 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_TEXT_SIZE);
511                                 xmlNodeSetContent(cur, (const xmlChar*)md->value);
512                                 xmlAddChild(root, cur);
513                                 isTextsize = true;
514                         } else if (!strcmp(md->key, TTS_METADATA_PITCH_SUPPORT)) {
515                                 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_PITCH_SUPPORT);
516                                 xmlNodeSetContent(cur, (const xmlChar*)md->value);
517                                 xmlAddChild(root, cur);
518                         } else {
519                                 LOGW("[WARNING] Unknown metadata type");
520                         }
521                 }
522                 iter = g_list_next(iter);
523         }
524
525         if (false == isTextsize) {
526                 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_TEXT_SIZE);
527                 xmlNodeSetContent(cur, (const xmlChar*)TTS_MAX_TEXT_SIZE);
528                 xmlAddChild(root, cur);
529                 LOGD("[DEBUG] Max text size is set as %s.", TTS_MAX_TEXT_SIZE);
530         }
531
532         cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_ID);
533         xmlNodeSetContent(cur, (const xmlChar*)pkgid);
534         xmlAddChild(root, cur);
535
536         LOGD("");
537
538         return 0;
539
540 }
541
542 static gchar* __get_user_type(GumUser *user)
543 {
544         GumUserType gumut = GUM_USERTYPE_NONE;
545         g_object_get(G_OBJECT(user), "usertype", &gumut, NULL);
546         gchar* user_type = g_strdup(gum_user_type_to_string(gumut));
547         return user_type;
548 }
549
550 static int __get_global_user_type(uid_t globalapp_uid)
551 {
552         if (globalapp_uid == g_uid) {
553                 g_user_type = g_strdup("admin");
554         } else {
555                 g_guser = gum_user_get_sync(g_uid, FALSE);
556                 if (NULL == g_guser) {
557                         LOGE("[ERROR] g_guser is NULL");
558                         return -1;
559                 }
560
561                 g_object_get(G_OBJECT(g_guser), "gid", &g_gid, NULL);
562                 g_user_type = __get_user_type(g_guser);
563         }
564
565         if (NULL == g_user_type) {
566                 LOGE("[ERROR] Fail to allocate memory");
567                 g_object_unref(g_guser);
568                 g_guser = NULL;
569                 return -1;
570         }
571
572         if (0 == strcmp(g_user_type, "none")) {
573                 /* GUM_USERTYPE_NONE */
574                 LOGE("[ERROR] Fail to get target uid");
575                 g_object_unref(g_guser);
576                 g_guser = NULL;
577                 G_FREE(g_user_type)
578                 return -1;
579         }
580
581         return 0;
582 }
583
584 EXPORT_API
585 int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
586 {
587         LOGD("METADATA INSTALL");
588         LOGD("pkgid(%s) appid(%s) list(%u)", pkgid, appid, g_list_length(list));
589
590         if (0 > pkgmgr_installer_info_get_target_uid(&g_uid)) {
591                 LOGE("[ERROR] Fail to get target uid");
592                 return 0;
593         }
594
595         LOGD("uid(%u)", g_uid);
596         printf("[Parser Debug][DEBUG] uid(%u)", g_uid);
597
598         uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
599         if (0 != __get_global_user_type(globalapp_uid)) {
600                 return -1;
601         }
602
603         /* global directory */
604         LOGD("[DEBUG] usertype: %s", g_user_type);
605         if (0 >= g_list_length(list)) {
606                 LOGE("[ERROR] No Engine Metadata");
607                 G_FREE(g_user_type)
608                 return 0;
609         }
610
611         if (0 != __write_metadata_inxml(pkgid, appid, list)) {
612                 LOGE("[ERROR] Fail to write metadata in the xml");
613                 xmlFreeDoc(g_doc);
614                 G_FREE(g_user_type)
615                 return -1;
616         }
617
618         /* Save in /opt/usr/data/ */
619         g_dir_config_base = strdup(TTS_GLOBAL_CONFIG_BASE);
620         g_dir_home = strdup(TTS_GLOBAL_HOME);
621         g_dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
622
623         if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_info) {
624                 LOGE("[ERROR] Fail to allocate memory");
625                 FREE(g_dir_config_base)
626                 FREE(g_dir_home)
627                 FREE(g_dir_engine_info)
628
629                 xmlFreeDoc(g_doc);
630                 G_FREE(g_user_type)
631                 return -1;
632         }
633
634         if (0 != __save_engine_info_xml(pkgid, g_user_type, g_uid, g_gid)) {
635                 LOGE("[ERROR] Fail to make engine info file");
636                 xmlFreeDoc(g_doc);
637                 G_FREE(g_user_type)
638                 return -1;
639         }
640
641
642         xmlFreeDoc(g_doc);
643         if (NULL != g_guser) {
644                 g_object_unref(g_guser);
645                 g_guser = NULL;
646         }
647         G_FREE(g_user_type)
648
649         FREE(g_dir_config_base)
650         FREE(g_dir_home)
651         FREE(g_dir_engine_info)
652
653         return 0;
654 }
655
656 EXPORT_API
657 int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
658 {
659         LOGD("METADATA UNINSTALL");
660         LOGD("pkgid(%s) appid(%s) list(%u)", pkgid, appid, g_list_length(list));
661
662         if (0 > pkgmgr_installer_info_get_target_uid(&g_uid)) {
663                 LOGE("[ERROR] Fail to get target uid");
664                 return 0;
665         }
666
667         LOGD("uid(%u)", g_uid);
668         printf("[Parser Debug][DEBUG] uid(%u)", g_uid);
669
670         uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
671         if (0 != __get_global_user_type(globalapp_uid)) {
672                 return -1;
673         }
674
675         /* global directory */
676         LOGD("[DEBUG] usertype: %s", g_user_type);
677
678         /* Remove files in /opt/usr/data/ */
679         g_dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
680         if (NULL == g_dir_engine_info) {
681                 LOGE("[ERROR] Fail to allocate memory");
682                 G_FREE(g_user_type)
683                 return -1;
684         }
685
686         if (0 != __remove_engine_info_xml(pkgid, g_user_type, g_uid)) {
687                 LOGE("[ERROR] Fail to remove engine info file");
688         }
689
690
691         if (NULL != g_guser) {
692                 g_object_unref(g_guser);
693                 g_guser = NULL;
694         }
695         G_FREE(g_user_type)
696
697         FREE(g_dir_engine_info)
698
699         LOGD("");
700         return 0;
701 }
702
703 EXPORT_API
704 int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
705 {
706         LOGD("METADATA UPGRADE");
707         LOGD("pkgid(%s) appid(%s) list(%u)", pkgid, appid, g_list_length(list));
708
709         PKGMGR_MDPARSER_PLUGIN_UNINSTALL(pkgid, appid, list);
710         PKGMGR_MDPARSER_PLUGIN_INSTALL(pkgid, appid, list);
711
712         LOGD("");
713         return 0;
714 }