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