Fix owner and group in engine-parser
[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 <tzplatform_config.h>
29 #include <systemd/sd-login.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
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")
59
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"
64
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"
67
68
69 typedef struct metadata {
70         const char *key;
71         const char *value;
72 } metadata;
73
74 static xmlDocPtr g_doc;
75 GumUser *g_guser = NULL;
76 uid_t g_uid = 301;      // app_fw
77 gid_t g_gid = 301;      // app_fw
78 GumUserType g_ut = GUM_USERTYPE_NONE;
79 gchar *g_user_type = NULL;
80
81 char *g_dir_config_base = NULL;
82 char *g_dir_home = NULL;
83 char *g_dir_engine_base = NULL;
84 char *g_dir_engine_info = NULL;
85
86 static int __create_engine_info_xml(const char *pkgid)
87 {
88         LOGD("=== Create engine info doc");
89         g_doc = xmlNewDoc((xmlChar*)"1.0");
90         if (NULL == g_doc) {
91                 LOGE("[ERROR] Fail to new doc");
92                 return -1;
93         }
94         LOGD("===");
95         return 0;
96 }
97
98 static int __save_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid, gid_t gid)
99 {
100         LOGD("=== Save engine info doc");
101         char *dir_config_base = NULL;
102         char *dir_home = NULL;
103         char *dir_engine_base = NULL;
104         char *dir_engine_info = NULL;
105
106         if (NULL == ut || (NULL != ut && 0 == strcmp(ut, "none"))) {
107                 LOGE("[ERROR] Usertype is NONE");
108                 return -1;
109         }
110
111         uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
112         uid_t tmp_uid = 0;
113         gid_t tmp_gid = 0;
114
115         LOGD("uid(%d)", uid);
116
117         if (globalapp_uid == uid) {
118                 /* Global app */
119                 dir_config_base = strdup(TTS_GLOBAL_CONFIG_BASE);
120                 dir_home = strdup(TTS_GLOBAL_HOME);
121                 dir_engine_base = strdup(TTS_GLOBAL_ENGINE_BASE);
122                 dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
123                 tmp_uid = 301;  // app_fw
124                 tmp_gid = 301;  // app_fw
125         } else {
126                 /* User app, Guest app, Security app */
127                 if (NULL != g_dir_config_base)
128                         dir_config_base = strdup(g_dir_config_base);
129                 if (NULL != g_dir_home)
130                         dir_home = strdup(g_dir_home);
131                 if (NULL != g_dir_engine_base)
132                         dir_engine_base = strdup(g_dir_engine_base);
133                 if (NULL != g_dir_engine_info)
134                         dir_engine_info = strdup(g_dir_engine_info);
135                 tmp_uid = uid;
136                 tmp_gid = gid;
137         }
138
139         if (NULL == dir_config_base || NULL == dir_home || NULL == dir_engine_base || NULL == dir_engine_info) {
140                 LOGE("[ERROR] Fail to allocate memory");
141                 if (NULL != dir_config_base) {
142                         free(dir_config_base);
143                         dir_config_base = NULL;
144                 }
145                 if (NULL != dir_home) {
146                         free(dir_home);
147                         dir_home = NULL;
148                 }
149                 if (NULL != dir_engine_base) {
150                         free(dir_engine_base);
151                         dir_engine_base = NULL;
152                 }
153                 if (NULL != dir_engine_info) {
154                         free(dir_engine_info);
155                         dir_engine_info = NULL;
156                 }
157                 return -1;
158         }
159
160         LOGD("[DEBUG] dir_engine_info(%s)", dir_engine_info);
161
162
163         /* Make directories */
164         if (0 != access(dir_config_base, F_OK)) {
165                 if (0 != mkdir(dir_config_base, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
166                         LOGE("[ERROR] Fail to make directory : %s", dir_config_base);
167                         free(dir_config_base);
168                         dir_config_base = NULL;
169                         free(dir_home);
170                         dir_home = NULL;
171                         free(dir_engine_base);
172                         dir_engine_base = NULL;
173                         free(dir_engine_info);
174                         dir_engine_info = NULL;
175                         return -1;
176                 } else {
177                         LOGD("Success to make directory : %s", dir_config_base);
178                         if (0 != chown(dir_config_base, tmp_uid, tmp_gid)) {
179                                 LOGD("[ERROR] Fail to change user and group");
180                         } else {
181                                 LOGD("[DEBUG] Success to change user and group");
182                         }
183                 }
184         }
185
186         if (0 != access(dir_home, F_OK)) {
187                 if (0 != mkdir(dir_home, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
188                         LOGE("[ERROR] Fail to make directory : %s", dir_home);
189                         free(dir_config_base);
190                         dir_config_base = NULL;
191                         free(dir_home);
192                         dir_home = NULL;
193                         free(dir_engine_base);
194                         dir_engine_base = NULL;
195                         free(dir_engine_info);
196                         dir_engine_info = NULL;
197                         return -1;
198                 } else {
199                         LOGD("Success to make directory : %s", dir_home);
200                         if (0 != chown(dir_home, tmp_uid, tmp_gid)) {
201                                 LOGD("[ERROR] Fail to change user and group");
202                         } else {
203                                 LOGD("[DEBUG] Success to change user and group");
204                         }
205                 }
206         }
207
208         if (0 != access(dir_engine_base, F_OK)) {
209                 if (0 != mkdir(dir_engine_base, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
210                         LOGE("[ERROR] Fail to make directory : %s", dir_engine_base);
211                         free(dir_config_base);
212                         dir_config_base = NULL;
213                         free(dir_home);
214                         dir_home = NULL;
215                         free(dir_engine_base);
216                         dir_engine_base = NULL;
217                         free(dir_engine_info);
218                         dir_engine_info = NULL;
219                         return -1;
220                 } else {
221                         LOGD("Success to make directory : %s", dir_engine_base);
222                         if (0 != chown(dir_engine_base, tmp_uid, tmp_gid)) {
223                                 LOGD("[ERROR] Fail to change user and group");
224                         } else {
225                                 LOGD("[DEBUG] Success to change user and group");
226                         }
227                 }
228         }
229
230         if (0 != access(dir_engine_info, F_OK)) {
231                 if (0 != mkdir(dir_engine_info, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
232                         LOGE("[ERROR] Fail to make directory : %s", dir_engine_info);
233                         free(dir_config_base);
234                         dir_config_base = NULL;
235                         free(dir_home);
236                         dir_home = NULL;
237                         free(dir_engine_base);
238                         dir_engine_base = NULL;
239                         free(dir_engine_info);
240                         dir_engine_info = NULL;
241                         return -1;
242                 } else {
243                         LOGD("Success to make directory : %s", dir_engine_info);
244                         if (0 != chown(dir_engine_info, tmp_uid, tmp_gid)) {
245                                 LOGD("[ERROR] Fail to change user and group");
246                         } else {
247                                 LOGD("[DEBUG] Success to change user and group");
248                         }
249                 }
250         }
251
252
253         char path[256] = {'\0',};
254         snprintf(path, 256, "%s/%s.xml", dir_engine_info, pkgid);
255         int ret = xmlSaveFormatFile(path, g_doc, 1);
256         LOGD("xmlSaveFile (%d)", ret);
257         if (0 == ret) {
258                 if (0 != chown(path, tmp_uid, tmp_gid)) {
259                         LOGD("[ERROR] Fail to change user and group");
260                 } else {
261                         LOGD("[DEBUG] Success to change user and group");
262                 }
263         }
264
265         free(dir_config_base);
266         dir_config_base = NULL;
267         free(dir_home);
268         dir_home = NULL;
269         free(dir_engine_base);
270         dir_engine_base = NULL;
271         free(dir_engine_info);
272         dir_engine_info = NULL;
273
274         LOGD("===");
275         return 0;
276 }
277
278 static int __remove_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid)
279 {
280         LOGD("=== Remove engine info doc");
281
282         char *dir_engine_info = NULL;
283
284         if (NULL == ut || (NULL != ut && 0 == strcmp(ut, "none"))) {
285                 LOGE("[ERROR] Usertype is NONE");
286                 return -1;
287         }
288
289         uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
290
291         LOGD("uid(%d)", uid);
292
293         if (globalapp_uid == uid) {
294                 /* Global app */
295                 dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
296         } else {
297                 /* User app, Guest app, Security app */
298                 if (NULL != g_dir_engine_info)
299                         dir_engine_info = strdup(g_dir_engine_info);
300         }
301
302         if (NULL == dir_engine_info) {
303                 LOGE("[ERROR] Fail to allocate memory");
304                 return -1;
305         }
306
307         LOGD("[DEBUG] dir_engine_info(%s)", dir_engine_info);
308
309
310         char path[256] = {'\0',};
311         snprintf(path, 256, "%s/%s.xml", dir_engine_info, pkgid);
312         if (0 == access(path, F_OK)) {
313                 LOGD("Remove engine info xml(%s)", path);
314                 if (0 != remove(path)) {
315                         LOGE("[ERROR] Fail to Remove engine info xml(%s)", path);
316                 }
317         }
318
319         free(dir_engine_info);
320         dir_engine_info = NULL;
321
322         LOGD("===");
323         return 0;
324 }
325
326 static void __insert_language_from_metadata(xmlNodePtr root, const char *language)
327 {
328         LOGD("==== Insert language");
329         char* voice = NULL;
330         char* lang = NULL;
331         char* type = NULL;
332
333         char *tmp_lang = NULL;
334         char *tmp_free = NULL;
335         tmp_free = tmp_lang = strdup(language);
336         if (NULL == tmp_lang) {
337                 LOGE("Fail to memory allocation");
338                 return;
339         }
340         xmlNodePtr voices_node = NULL;
341         xmlNodePtr voice_node = NULL;
342
343         voices_node = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_VOICE_SET);
344
345         voice = strsep(&tmp_lang, ",");
346         while (NULL != voice) {
347                 LOGD("voice (%s)", voice);
348                 voice_node = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_VOICE);
349                 lang = strsep(&voice, ":");
350                 LOGD("lang (%s)", lang);
351                 type = strsep(&voice, " ");
352                 LOGD("type (%s)", type);
353                 xmlSetProp(voice_node, (const xmlChar*)TTS_TAG_ENGINE_VOICE_TYPE, (const xmlChar*)type);
354                 xmlNodeSetContent(voice_node, (const xmlChar*)lang);
355                 xmlAddChild(voices_node, voice_node);
356                 voice = strsep(&tmp_lang, ",");
357         }
358         xmlAddChild(root, voices_node);
359
360         free(tmp_free);
361         tmp_free = NULL;
362 }
363
364 static int __write_metadata_inxml(const char *pkgid, const char *appid, GList *list)
365 {
366         GList *iter = NULL;
367         metadata *md = NULL;
368
369         __create_engine_info_xml(pkgid);
370
371         xmlNodePtr root = NULL;
372         xmlNodePtr cur = NULL;
373
374         root = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_BASE);
375         if (NULL == root) {
376                 LOGE("[ERROR] Fail to get new node");
377 //              xmlFreeDoc(g_doc);
378                 return -1;
379         }
380         xmlDocSetRootElement(g_doc, root);
381
382         /* Save name */
383         cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_NAME);
384         xmlNodeSetContent(cur, (const xmlChar*)pkgid);
385         xmlAddChild(root, cur);
386
387
388         iter = g_list_first(list);
389         while (NULL != iter) {
390                 md = (metadata *)iter->data;
391                 if (NULL != md && NULL != md->key) {
392                         LOGD(" - key(%s) value(%s)", md->key, md->value);
393                         if (!strcmp(md->key, TTS_METADATA_LANGUAGE)) {
394                                 __insert_language_from_metadata(root, md->value);
395                         } else if (!strcmp(md->key, TTS_METADATA_CREDENTIAL_REQUIRED)) {
396                                 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_CREDENTIAL);
397                                 xmlNodeSetContent(cur, (const xmlChar*)md->value);
398                                 xmlAddChild(root, cur);
399                         } else {
400                                 LOGW("[WARNING] Unknown metadata type");
401                         }
402                 }
403                 iter = g_list_next(iter);
404         }
405
406         cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_ID);
407         xmlNodeSetContent(cur, (const xmlChar*)pkgid);
408         xmlAddChild(root, cur);
409
410         LOGD("");
411
412         return 0;
413
414 }
415
416 EXPORT_API
417 int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
418 {
419         LOGD("METADATA INSTALL");
420         LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
421
422         int ret = -1;
423         ret = pkgmgr_installer_info_get_target_uid(&g_uid);
424         if (ret < 0) {
425                 LOGE("[ERROR] Fail to get target uid");
426                 return 0;
427         } else {
428                 LOGD("uid(%d)", g_uid);
429                 printf("[Parser Debug][DEBUG] uid(%d)", g_uid);
430         }
431
432         uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
433         if (globalapp_uid == g_uid) {
434                 g_user_type = g_strdup("admin");
435         } else {
436                 g_guser = gum_user_get_sync(g_uid, FALSE);
437                 if (NULL == g_guser) {
438                         LOGE("[ERROR] g_guser is NULL");
439                         return -1;
440                 }
441
442                 g_object_get(G_OBJECT(g_guser), "gid", &g_gid, NULL);
443                 g_object_get(G_OBJECT(g_guser), "usertype", &g_ut, NULL);
444                 g_user_type = g_strdup(gum_user_type_to_string(g_ut));
445         }
446
447         if (NULL == g_user_type) {
448                 LOGE("[ERROR] Fail to allocate memory");
449                 if (NULL != g_guser) {
450                         g_object_unref(g_guser);
451                         g_guser = NULL;
452                 }
453                 return -1;
454         }
455
456         if (0 == strcmp(g_user_type, "none")) {
457                 /* GUM_USERTYPE_NONE */
458                 LOGE("[ERROR] Fail to get target uid");
459                 g_object_unref(g_guser);
460                 g_guser = NULL;
461                 g_free(g_user_type);
462                 return -1;
463         }
464
465         if (globalapp_uid == g_uid) {
466                 /* global directory */
467                 LOGD("[DEBUG] usertype: %s", g_user_type);
468                 if (0 >= g_list_length(list)) {
469                         LOGE("[ERROR] No Engine Metadata");
470                         g_free(g_user_type);
471                         return 0;
472                 }
473
474                 if (0 != __write_metadata_inxml(pkgid, appid, list)) {
475                         LOGE("[ERROR] Fail to write metadata in the xml");
476                         xmlFreeDoc(g_doc);
477                         g_free(g_user_type);
478                         return -1;
479                 }
480
481                 /* Save in /etc/skel/share/ */
482                 g_dir_config_base = strdup(TTS_GLOBAL_CONFIG_BASE);
483                 g_dir_home = strdup(TTS_GLOBAL_HOME);
484                 g_dir_engine_base = strdup(TTS_GLOBAL_ENGINE_BASE);
485                 g_dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
486
487                 if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) {
488                         LOGE("[ERROR] Fail to allocate memory");
489                         if (NULL != g_dir_config_base) {
490                                 free(g_dir_config_base);
491                                 g_dir_config_base = NULL;
492                         }
493                         if (NULL != g_dir_home) {
494                                 free(g_dir_home);
495                                 g_dir_home = NULL;
496                         }
497                         if (NULL != g_dir_engine_base) {
498                                 free(g_dir_engine_base);
499                                 g_dir_engine_base = NULL;
500                         }
501                         if (NULL != g_dir_engine_info) {
502                                 free(g_dir_engine_info);
503                                 g_dir_engine_info = NULL;
504                         }
505                         xmlFreeDoc(g_doc);
506                         g_free(g_user_type);
507                         return -1;
508                 }
509
510                 if (0 != __save_engine_info_xml(pkgid, g_user_type, g_uid, g_gid)) {
511                         LOGE("[ERROR] Fail to make engine info file");
512                         xmlFreeDoc(g_doc);
513                         g_free(g_user_type);
514                         return -1;
515                 }
516
517                 /* Get user data by using libgum */
518
519                 GumUserService *gus = NULL;
520                 GumUserList *users = NULL;
521                 GumUserList *iter = NULL;
522                 GumUser *user = NULL;
523                 gchar **query;
524                 GumUserType gumut = GUM_USERTYPE_NONE;
525                 gchar *user_type = NULL;
526
527                 uid_t uid;
528                 gid_t gid;
529                 gchar *home_dir = NULL;
530
531                 gus = gum_user_service_create_sync(TRUE);
532                 if (!gus) {
533                         LOGE("Failed to create gum user service");
534                         g_free(g_user_type);
535                         return -1;
536                 }
537
538                 query = g_strsplit("admin,normal", ",", -1);
539
540                 users = gum_user_service_get_user_list_sync(gus, (const gchar *const *)query);
541                 g_strfreev(query);
542
543                 if (!users) {
544                         LOGE("Failed to get gum user list");
545                         g_object_unref(gus);
546                         gus = NULL;
547                         g_free(g_user_type);
548                         return -1;
549                 }
550
551                 /* Make new user list */
552
553                 iter = users;
554                 while (iter != NULL) {
555                         user = (GumUser*) iter->data;
556                         g_object_get(G_OBJECT(user), "uid", &uid, NULL);
557                         if (NULL != home_dir) {
558                                 free(home_dir);
559                                 home_dir = NULL;
560                         }
561                         g_object_get(G_OBJECT(user), "gid", &gid, NULL);
562                         g_object_get(G_OBJECT(user), "homedir", &home_dir, NULL);
563                         g_object_get(G_OBJECT(user), "usertype", &gumut, NULL);
564                         user_type = g_strdup(gum_user_type_to_string(gumut));
565                         if (NULL == user_type) {
566                                 gum_user_service_list_free(users);
567                                 g_object_unref(gus);
568                                 gus = NULL;
569                                 return -1;
570                         }
571
572                         LOGD("[DEBUG] user info");
573                         if (NULL != home_dir) {
574                                 LOGD("[DEBUG] uid(%d), gid(%d),  user_type(%s), home_dir(%s)", uid, gid, user_type, home_dir);
575
576                                 g_dir_config_base = (char*)calloc(strlen(home_dir) + 14, sizeof(char));
577                                 g_dir_home = (char*)calloc(strlen(home_dir) + 18, sizeof(char));
578                                 g_dir_engine_base = (char*)calloc(strlen(home_dir) + 22, sizeof(char));
579                                 g_dir_engine_info = (char*)calloc(strlen(home_dir) + 34, sizeof(char));
580
581                                 if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) {
582                                         LOGE("[ERROR] Fail to allocate memory");
583                                         if (NULL != g_dir_config_base) {
584                                                 free(g_dir_config_base);
585                                                 g_dir_config_base = NULL;
586                                         }
587                                         if (NULL != g_dir_home) {
588                                                 free(g_dir_home);
589                                                 g_dir_home = NULL;
590                                         }
591                                         if (NULL != g_dir_engine_base) {
592                                                 free(g_dir_engine_base);
593                                                 g_dir_engine_base = NULL;
594                                         }
595                                         if (NULL != g_dir_engine_info) {
596                                                 free(g_dir_engine_info);
597                                                 g_dir_engine_info = NULL;
598                                         }
599                                         gum_user_service_list_free(users);
600                                         g_object_unref(gus);
601                                         gus = NULL;
602                                         return -1;
603                                 }
604                                 snprintf(g_dir_config_base, strlen(home_dir) + 14, "%s/share/.voice", home_dir);
605                                 snprintf(g_dir_home, strlen(home_dir) + 18, "%s/share/.voice/tts", home_dir);
606                                 snprintf(g_dir_engine_base, strlen(home_dir) + 22, "%s/share/.voice/tts/1.0", home_dir);
607                                 snprintf(g_dir_engine_info, strlen(home_dir) + 34, "%s/share/.voice/tts/1.0/engine-info", home_dir);
608
609                                 LOGD("[DEBUG] g_dir_engine_info(%s)", g_dir_engine_info);
610
611                                 if (0 != __save_engine_info_xml(pkgid, user_type, uid, gid)) {
612                                         LOGE("[ERROR] Fail to make engine info file");
613                                 }
614
615                                 free(g_dir_config_base);
616                                 g_dir_config_base = NULL;
617                                 free(g_dir_home);
618                                 g_dir_home = NULL;
619                                 free(g_dir_engine_base);
620                                 g_dir_engine_base = NULL;
621                                 free(g_dir_engine_info);
622                                 g_dir_engine_info = NULL;
623
624                                 g_free(user_type);
625                                 user_type = NULL;
626                                 free(home_dir);
627                                 home_dir = NULL;
628
629                                 iter = g_list_next(iter);
630                         } else {
631                                 iter = g_list_next(iter);
632                         }
633
634                         if (NULL != user_type) {
635                                 g_free(user_type);
636                                 user_type = NULL;
637                         }
638                 }
639
640                 gum_user_service_list_free(users);
641                 g_object_unref(gus);
642                 gus = NULL;
643         } else {
644                 /* user directory */
645                 LOGD("[DEBUG] usertype: %s", g_user_type);
646
647                 ret = tzplatform_set_user(g_uid);
648                 if (ret < 0) {
649                         LOGE("[ERROR] Invalid uid");
650                         g_object_unref(g_guser);
651                         g_guser = NULL;
652                         g_free(g_user_type);
653                         return 0;
654                 } else {
655                         LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
656                         printf("[Parser Debug][DEBUG] TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
657                 }
658
659                 if (0 >= g_list_length(list)) {
660                         LOGE("[ERROR] No Engine Metadata");
661                         g_object_unref(g_guser);
662                         g_guser = NULL;
663                         g_free(g_user_type);
664                         return 0;
665                 }
666
667                 if (0 != __write_metadata_inxml(pkgid, appid, list)) {
668                         LOGE("[ERROR] Fail to write metadata in the xml");
669                         xmlFreeDoc(g_doc);
670                         g_object_unref(g_guser);
671                         g_guser = NULL;
672                         g_free(g_user_type);
673                         return -1;
674                 }
675
676                 g_dir_config_base = strdup(TTS_CONFIG_BASE);
677                 g_dir_home = strdup(TTS_HOME);
678                 g_dir_engine_base = strdup(TTS_ENGINE_BASE);
679                 g_dir_engine_info = strdup(TTS_ENGINE_INFO);
680
681                 if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) {
682                         LOGE("[ERROR] Fail to allocate memory");
683                         if (NULL != g_dir_config_base) {
684                                 free(g_dir_config_base);
685                                 g_dir_config_base = NULL;
686                         }
687                         if (NULL != g_dir_home) {
688                                 free(g_dir_home);
689                                 g_dir_home = NULL;
690                         }
691                         if (NULL != g_dir_engine_base) {
692                                 free(g_dir_engine_base);
693                                 g_dir_engine_base = NULL;
694                         }
695                         if (NULL != g_dir_engine_info) {
696                                 free(g_dir_engine_info);
697                                 g_dir_engine_info = NULL;
698                         }
699                         xmlFreeDoc(g_doc);
700                         g_object_unref(g_guser);
701                         g_guser = NULL;
702                         g_free(g_user_type);
703                         return -1;
704                 }
705
706                 if (0 != __save_engine_info_xml(pkgid, g_user_type, g_uid, g_gid)) {
707                         LOGE("[ERROR] Fail to make engine info file");
708                         xmlFreeDoc(g_doc);
709                         if (NULL != g_guser) {
710                                 g_object_unref(g_guser);
711                                 g_guser = NULL;
712                         }
713                         g_free(g_user_type);
714                         return -1;
715                 }
716         }
717
718         xmlFreeDoc(g_doc);
719         if (NULL != g_guser) {
720                 g_object_unref(g_guser);
721                 g_guser = NULL;
722         }
723         g_free(g_user_type);
724
725         if (NULL != g_dir_config_base) {
726                 free(g_dir_config_base);
727                 g_dir_config_base = NULL;
728         }
729         if (NULL != g_dir_home) {
730                 free(g_dir_home);
731                 g_dir_home = NULL;
732         }
733         if (NULL != g_dir_engine_base) {
734                 free(g_dir_engine_base);
735                 g_dir_engine_base = NULL;
736         }
737         if (NULL != g_dir_engine_info) {
738                 free(g_dir_engine_info);
739                 g_dir_engine_info = NULL;
740         }
741
742         return 0;
743 }
744
745 EXPORT_API
746 int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
747 {
748         LOGD("METADATA UNINSTALL");
749         LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
750
751         int ret = -1;
752         ret = pkgmgr_installer_info_get_target_uid(&g_uid);
753         if (ret < 0) {
754                 LOGE("[ERROR] Fail to get target uid");
755                 return 0;
756         } else {
757                 LOGD("uid(%d)", g_uid);
758                 printf("[Parser Debug][DEBUG] uid(%d)", g_uid);
759         }
760
761         uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
762         if (globalapp_uid == g_uid) {
763                 g_user_type = g_strdup("admin");
764         } else {
765                 g_guser = gum_user_get_sync(g_uid, FALSE);
766                 if (NULL == g_guser) {
767                         LOGE("[ERROR] g_guser is NULL");
768                         return -1;
769                 }
770
771                 g_object_get(G_OBJECT(g_guser), "usertype", &g_ut, NULL);
772                 g_user_type = g_strdup(gum_user_type_to_string(g_ut));
773         }
774
775         if (NULL == g_user_type) {
776                 LOGE("[ERROR] Fail to allocate memory");
777                 if (NULL != g_guser) {
778                         g_object_unref(g_guser);
779                         g_guser = NULL;
780                 }
781                 return -1;
782         }
783
784         if (0 == strcmp(g_user_type, "none")) {
785                 /* GUM_USERTYPE_NONE */
786                 LOGE("[ERROR] Fail to get target uid");
787                 g_object_unref(g_guser);
788                 g_guser = NULL;
789                 g_free(g_user_type);
790                 return -1;
791         }
792
793         if (globalapp_uid == g_uid) {
794                 /* global directory */
795                 LOGD("[DEBUG] usertype: %s", g_user_type);
796
797                 /* Remove files in /etc/skel/share/ */
798                 g_dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
799                 if (NULL == g_dir_engine_info) {
800                         LOGE("[ERROR] Fail to allocate memory");
801                         g_free(g_user_type);
802                         return -1;
803                 }
804
805                 if (0 != __remove_engine_info_xml(pkgid, g_user_type, g_uid)) {
806                         LOGE("[ERROR] Fail to remove engine info file");
807                 }
808
809                 /* Get user data by using libgum */
810
811                 GumUserService *gus = NULL;
812                 GumUserList *users = NULL;
813                 GumUserList *iter = NULL;
814                 GumUser *user = NULL;
815                 gchar **query;
816                 GumUserType gumut = GUM_USERTYPE_NONE;
817                 gchar *user_type = NULL;
818
819                 uid_t uid;
820                 gchar *home_dir = NULL;
821
822                 GList *md_iter = NULL;
823                 metadata *md = NULL;
824
825                 gus = gum_user_service_create_sync(TRUE);
826                 if (!gus) {
827                         LOGE("Failed to create gum user service");
828                         g_free(g_user_type);
829                         return -1;
830                 }
831
832                 query = g_strsplit("admin,normal", ",", -1);
833
834                 users = gum_user_service_get_user_list_sync(gus, (const gchar *const *)query);
835                 g_strfreev(query);
836
837                 if (!users) {
838                         LOGE("Failed to get gum user list");
839                         g_object_unref(gus);
840                         gus = NULL;
841                         g_free(g_user_type);
842                         return -1;
843                 }
844
845                 /* Make new user list */
846
847                 iter = users;
848                 while (iter != NULL) {
849                         user = (GumUser*) iter->data;
850                         g_object_get(G_OBJECT(user), "uid", &uid, NULL);
851                         if (NULL != home_dir) {
852                                 free(home_dir);
853                                 home_dir = NULL;
854                         }
855                         g_object_get(G_OBJECT(user), "homedir", &home_dir, NULL);
856                         g_object_get(G_OBJECT(user), "usertype", &gumut, NULL);
857                         user_type = g_strdup(gum_user_type_to_string(gumut));
858                         if (NULL == user_type) {
859                                 gum_user_service_list_free(users);
860                                 g_object_unref(gus);
861                                 gus = NULL;
862                                 return -1;
863                         }
864
865                         if (NULL != home_dir) {
866                                 g_dir_engine_info = (char*)calloc(strlen(home_dir) + 34, sizeof(char));
867                                 if (NULL == g_dir_engine_info) {
868                                         gum_user_service_list_free(users);
869                                         g_object_unref(gus);
870                                         gus = NULL;
871                                         return -1;
872                                 }
873
874                                 snprintf(g_dir_engine_info, strlen(home_dir) + 34, "%s/share/.voice/tts/1.0/engine-info", home_dir);
875
876                                 md_iter = g_list_first(list);
877                                 while (NULL != md_iter) {
878                                         md = (metadata *)md_iter->data;
879                                         LOGD(" - key(%s) value(%s)", md->key, md->value);
880                                         md_iter = g_list_next(md_iter);
881                                 }
882
883                                 if (0 != __remove_engine_info_xml(pkgid, user_type, uid)) {
884                                         LOGE("[ERROR] Fail to remove engine info file");
885                                 }
886
887                                 free(home_dir);
888                                 home_dir = NULL;
889
890                                 free(g_dir_engine_info);
891                                 g_dir_engine_info = NULL;
892
893                                 g_free(user_type);
894
895                                 LOGD("Finish release memory");
896                                 iter = g_list_next(iter);
897                                 LOGD("Finish next iter");
898                         } else {
899                                 iter = g_list_next(iter);
900                         }
901                 }
902
903                 gum_user_service_list_free(users);
904                 g_object_unref(gus);
905                 gus = NULL;
906         } else {
907                 /* user directory */
908                 LOGD("[DEBUG] usertype: %s", g_user_type);
909
910                 ret = tzplatform_set_user(g_uid);
911                 if (ret < 0) {
912                         LOGE("[ERROR] Invalid uid");
913                         g_object_unref(g_guser);
914                         g_guser = NULL;
915                         g_free(g_user_type);
916                         return -1;
917                 } else {
918                         LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
919                         printf("[Parser Debug][DEBUG] TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
920                 }
921
922                 g_dir_engine_info = strdup(TTS_ENGINE_INFO);
923                 if (NULL == g_dir_engine_info) {
924                         LOGE("[ERROR] Fail to allocate memory");
925                         g_object_unref(g_guser);
926                         g_guser = NULL;
927                         g_free(g_user_type);
928                         return -1;
929                 }
930
931                 if (0 != __remove_engine_info_xml(pkgid, g_user_type, g_uid)) {
932                         LOGE("[ERROR] Fail to remove engine info file");
933                 }
934
935         }
936
937         if (NULL != g_guser) {
938                 g_object_unref(g_guser);
939                 g_guser = NULL;
940         }
941         g_free(g_user_type);
942
943         if (NULL != g_dir_engine_info) {
944                 free(g_dir_engine_info);
945                 g_dir_engine_info = NULL;
946         }
947
948         LOGD("");
949         return 0;
950 }
951
952 EXPORT_API
953 int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
954 {
955         LOGD("METADATA UPGRADE");
956         LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
957
958         PKGMGR_MDPARSER_PLUGIN_UNINSTALL(pkgid, appid, list);
959         PKGMGR_MDPARSER_PLUGIN_INSTALL(pkgid, appid, list);
960
961         LOGD("");
962         return 0;
963 }