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