Merge "Add error tolerance with dbus signal handling" into tizen
[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                 /* Save in /etc/skel/share/ */
447                 g_dir_config_base = strdup(TTS_GLOBAL_CONFIG_BASE);
448                 g_dir_home = strdup(TTS_GLOBAL_HOME);
449                 g_dir_engine_base = strdup(TTS_GLOBAL_ENGINE_BASE);
450                 g_dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
451
452                 if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) {
453                         LOGE("[ERROR] Fail to allocate memory");
454                         if (NULL != g_dir_config_base) {
455                                 free(g_dir_config_base);
456                                 g_dir_config_base = NULL;
457                         }
458                         if (NULL != g_dir_home) {
459                                 free(g_dir_home);
460                                 g_dir_home = NULL;
461                         }
462                         if (NULL != g_dir_engine_base) {
463                                 free(g_dir_engine_base);
464                                 g_dir_engine_base = NULL;
465                         }
466                         if (NULL != g_dir_engine_info) {
467                                 free(g_dir_engine_info);
468                                 g_dir_engine_info = NULL;
469                         }
470                         xmlFreeDoc(g_doc);
471                         g_free(g_user_type);
472                         return -1;
473                 }
474
475                 if (0 != __save_engine_info_xml(pkgid, g_user_type, g_uid)) {
476                         LOGE("[ERROR] Fail to make engine info file");
477                         xmlFreeDoc(g_doc);
478                         g_free(g_user_type);
479                         return -1;
480                 }
481
482                 /* Get user data by using libgum */
483
484                 GumUserService *gus = NULL;
485                 GumUserList *users = NULL;
486                 GumUserList *iter = NULL;
487                 GumUser *user = NULL;
488                 gchar **query;
489                 GumUserType gumut = GUM_USERTYPE_NONE;
490                 gchar *user_type = NULL;
491
492                 uid_t uid;
493                 gchar *home_dir = NULL;
494
495                 gus = gum_user_service_create_sync(TRUE);
496                 if (!gus) {
497                         LOGE("Failed to create gum user service");
498                         g_free(g_user_type);
499                         return -1;
500                 }
501
502                 query = g_strsplit("admin,normal", ",", -1);
503
504                 users = gum_user_service_get_user_list_sync(gus, (const gchar *const *)query);
505                 g_strfreev(query);
506
507                 if (!users) {
508                         LOGE("Failed to get gum user list");
509                         g_object_unref(gus);
510                         gus = NULL;
511                         g_free(g_user_type);
512                         return -1;
513                 }
514
515                 /* Make new user list */
516
517                 iter = users;
518                 while (iter != NULL) {
519                         user = (GumUser*) iter->data;
520                         g_object_get(G_OBJECT(user), "uid", &uid, NULL);
521                         if (NULL != home_dir) {
522                                 free(home_dir);
523                                 home_dir = NULL;
524                         }
525                         g_object_get(G_OBJECT(user), "homedir", &home_dir, NULL);
526                         g_object_get(G_OBJECT(user), "usertype", &gumut, NULL);
527                         user_type = g_strdup(gum_user_type_to_string(gumut));
528                         if (NULL == user_type) {
529                                 gum_user_service_list_free(users);
530                                 g_object_unref(gus);
531                                 gus = NULL;
532                                 return -1;
533                         }
534
535                         LOGD("[DEBUG] user info");
536                         if (NULL != home_dir) {
537                                 LOGD("[DEBUG] uid(%d), user_type(%s), home_dir(%s)", uid, user_type, home_dir);
538
539                                 g_dir_config_base = (char*)calloc(strlen(home_dir) + 14, sizeof(char));
540                                 g_dir_home = (char*)calloc(strlen(home_dir) + 18, sizeof(char));
541                                 g_dir_engine_base = (char*)calloc(strlen(home_dir) + 22, sizeof(char));
542                                 g_dir_engine_info = (char*)calloc(strlen(home_dir) + 34, sizeof(char));
543
544                                 if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) {
545                                         LOGE("[ERROR] Fail to allocate memory");
546                                         if (NULL != g_dir_config_base) {
547                                                 free(g_dir_config_base);
548                                                 g_dir_config_base = NULL;
549                                         }
550                                         if (NULL != g_dir_home) {
551                                                 free(g_dir_home);
552                                                 g_dir_home = NULL;
553                                         }
554                                         if (NULL != g_dir_engine_base) {
555                                                 free(g_dir_engine_base);
556                                                 g_dir_engine_base = NULL;
557                                         }
558                                         if (NULL != g_dir_engine_info) {
559                                                 free(g_dir_engine_info);
560                                                 g_dir_engine_info = NULL;
561                                         }
562                                         gum_user_service_list_free(users);
563                                         g_object_unref(gus);
564                                         gus = NULL;
565                                         return -1;
566                                 }
567                                 snprintf(g_dir_config_base, strlen(home_dir) + 14, "%s/share/.voice", home_dir);
568                                 snprintf(g_dir_home, strlen(home_dir) + 18, "%s/share/.voice/tts", home_dir);
569                                 snprintf(g_dir_engine_base, strlen(home_dir) + 22, "%s/share/.voice/tts/1.0", home_dir);
570                                 snprintf(g_dir_engine_info, strlen(home_dir) + 34, "%s/share/.voice/tts/1.0/engine-info", home_dir);
571
572                                 LOGD("[DEBUG] g_dir_engine_info(%s)", g_dir_engine_info);
573
574                                 if (0 != __save_engine_info_xml(pkgid, user_type, uid)) {
575                                         LOGE("[ERROR] Fail to make engine info file");
576                                 }
577
578                                 free(g_dir_config_base);
579                                 g_dir_config_base = NULL;
580                                 free(g_dir_home);
581                                 g_dir_home = NULL;
582                                 free(g_dir_engine_base);
583                                 g_dir_engine_base = NULL;
584                                 free(g_dir_engine_info);
585                                 g_dir_engine_info = NULL;
586
587                                 g_free(user_type);
588                                 user_type = NULL;
589                                 free(home_dir);
590                                 home_dir = NULL;
591
592                                 iter = g_list_next(iter);
593                         } else {
594                                 iter = g_list_next(iter);
595                         }
596
597                         if (NULL != user_type) {
598                                 g_free(user_type);
599                                 user_type = NULL;
600                         }
601                 }
602
603                 gum_user_service_list_free(users);
604                 g_object_unref(gus);
605                 gus = NULL;
606         } else {
607                 /* user directory */
608                 LOGD("[DEBUG] usertype: %s", g_user_type);
609
610                 ret = tzplatform_set_user(g_uid);
611                 if (ret < 0) {
612                         LOGE("[ERROR] Invalid uid");
613                         g_object_unref(g_guser);
614                         g_guser = NULL;
615                         g_free(g_user_type);
616                         return 0;
617                 } else {
618                         LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
619                         printf("[Parser Debug][DEBUG] TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
620                 }
621
622                 if (0 >= g_list_length(list)) {
623                         LOGE("[ERROR] No Engine Metadata");
624                         g_object_unref(g_guser);
625                         g_guser = NULL;
626                         g_free(g_user_type);
627                         return 0;
628                 }
629
630                 if (0 != __write_metadata_inxml(pkgid, appid, list)) {
631                         LOGE("[ERROR] Fail to write metadata in the xml");
632                         xmlFreeDoc(g_doc);
633                         g_object_unref(g_guser);
634                         g_guser = NULL;
635                         g_free(g_user_type);
636                         return -1;
637                 }
638
639                 g_dir_config_base = strdup(TTS_CONFIG_BASE);
640                 g_dir_home = strdup(TTS_HOME);
641                 g_dir_engine_base = strdup(TTS_ENGINE_BASE);
642                 g_dir_engine_info = strdup(TTS_ENGINE_INFO);
643
644                 if (NULL == g_dir_config_base || NULL == g_dir_home || NULL == g_dir_engine_base || NULL == g_dir_engine_info) {
645                         LOGE("[ERROR] Fail to allocate memory");
646                         if (NULL != g_dir_config_base) {
647                                 free(g_dir_config_base);
648                                 g_dir_config_base = NULL;
649                         }
650                         if (NULL != g_dir_home) {
651                                 free(g_dir_home);
652                                 g_dir_home = NULL;
653                         }
654                         if (NULL != g_dir_engine_base) {
655                                 free(g_dir_engine_base);
656                                 g_dir_engine_base = NULL;
657                         }
658                         if (NULL != g_dir_engine_info) {
659                                 free(g_dir_engine_info);
660                                 g_dir_engine_info = NULL;
661                         }
662                         xmlFreeDoc(g_doc);
663                         g_object_unref(g_guser);
664                         g_guser = NULL;
665                         g_free(g_user_type);
666                         return -1;
667                 }
668
669                 if (0 != __save_engine_info_xml(pkgid, g_user_type, g_uid)) {
670                         LOGE("[ERROR] Fail to make engine info file");
671                         xmlFreeDoc(g_doc);
672                         if (NULL != g_guser) {
673                                 g_object_unref(g_guser);
674                                 g_guser = NULL;
675                         }
676                         g_free(g_user_type);
677                         return -1;
678                 }
679         }
680
681         xmlFreeDoc(g_doc);
682         if (NULL != g_guser) {
683                 g_object_unref(g_guser);
684                 g_guser = NULL;
685         }
686         g_free(g_user_type);
687
688         if (NULL != g_dir_config_base) {
689                 free(g_dir_config_base);
690                 g_dir_config_base = NULL;
691         }
692         if (NULL != g_dir_home) {
693                 free(g_dir_home);
694                 g_dir_home = NULL;
695         }
696         if (NULL != g_dir_engine_base) {
697                 free(g_dir_engine_base);
698                 g_dir_engine_base = NULL;
699         }
700         if (NULL != g_dir_engine_info) {
701                 free(g_dir_engine_info);
702                 g_dir_engine_info = NULL;
703         }
704
705         return 0;
706 }
707
708 EXPORT_API
709 int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
710 {
711         LOGD("METADATA UNINSTALL");
712         LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
713
714         int ret = -1;
715         ret = pkgmgr_installer_info_get_target_uid(&g_uid);
716         if (ret < 0) {
717                 LOGE("[ERROR] Fail to get target uid");
718                 return 0;
719         } else {
720                 LOGD("uid(%d)", g_uid);
721                 printf("[Parser Debug][DEBUG] uid(%d)", g_uid);
722         }
723
724         uid_t globalapp_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
725         if (globalapp_uid == g_uid) {
726                 g_user_type = g_strdup("admin");
727         } else {
728                 g_guser = gum_user_get_sync(g_uid, FALSE);
729                 if (NULL == g_guser) {
730                         LOGE("[ERROR] g_guser is NULL");
731                         return -1;
732                 }
733
734                 g_object_get(G_OBJECT(g_guser), "usertype", &g_ut, NULL);
735                 g_user_type = g_strdup(gum_user_type_to_string(g_ut));
736         }
737
738         if (NULL == g_user_type) {
739                 LOGE("[ERROR] Fail to allocate memory");
740                 if (NULL != g_guser) {
741                         g_object_unref(g_guser);
742                         g_guser = NULL;
743                 }
744                 return -1;
745         }
746
747         if (0 == strcmp(g_user_type, "none")) {
748                 /* GUM_USERTYPE_NONE */
749                 LOGE("[ERROR] Fail to get target uid");
750                 g_object_unref(g_guser);
751                 g_guser = NULL;
752                 g_free(g_user_type);
753                 return -1;
754         }
755
756         if (globalapp_uid == g_uid) {
757                 /* global directory */
758                 LOGD("[DEBUG] usertype: %s", g_user_type);
759
760                 /* Remove files in /etc/skel/share/ */
761                 g_dir_engine_info = strdup(TTS_GLOBAL_ENGINE_INFO);
762                 if (NULL == g_dir_engine_info) {
763                         LOGE("[ERROR] Fail to allocate memory");
764                         g_free(g_user_type);
765                         return -1;
766                 }
767
768                 if (0 != __remove_engine_info_xml(pkgid, g_user_type, g_uid)) {
769                         LOGE("[ERROR] Fail to remove engine info file");
770                 }
771
772                 /* Get user data by using libgum */
773
774                 GumUserService *gus = NULL;
775                 GumUserList *users = NULL;
776                 GumUserList *iter = NULL;
777                 GumUser *user = NULL;
778                 gchar **query;
779                 GumUserType gumut = GUM_USERTYPE_NONE;
780                 gchar *user_type = NULL;
781
782                 uid_t uid;
783                 gchar *home_dir = NULL;
784
785                 GList *md_iter = NULL;
786                 metadata *md = NULL;
787
788                 gus = gum_user_service_create_sync(TRUE);
789                 if (!gus) {
790                         LOGE("Failed to create gum user service");
791                         g_free(g_user_type);
792                         return -1;
793                 }
794
795                 query = g_strsplit("admin,normal", ",", -1);
796
797                 users = gum_user_service_get_user_list_sync(gus, (const gchar *const *)query);
798                 g_strfreev(query);
799
800                 if (!users) {
801                         LOGE("Failed to get gum user list");
802                         g_object_unref(gus);
803                         gus = NULL;
804                         g_free(g_user_type);
805                         return -1;
806                 }
807
808                 /* Make new user list */
809
810                 iter = users;
811                 while (iter != NULL) {
812                         user = (GumUser*) iter->data;
813                         g_object_get(G_OBJECT(user), "uid", &uid, NULL);
814                         if (NULL != home_dir) {
815                                 free(home_dir);
816                                 home_dir = NULL;
817                         }
818                         g_object_get(G_OBJECT(user), "homedir", &home_dir, NULL);
819                         g_object_get(G_OBJECT(user), "usertype", &gumut, NULL);
820                         user_type = g_strdup(gum_user_type_to_string(gumut));
821                         if (NULL == user_type) {
822                                 gum_user_service_list_free(users);
823                                 g_object_unref(gus);
824                                 gus = NULL;
825                                 return -1;
826                         }
827
828                         if (NULL != home_dir) {
829                                 g_dir_engine_info = (char*)calloc(strlen(home_dir) + 34, sizeof(char));
830                                 if (NULL == g_dir_engine_info) {
831                                         gum_user_service_list_free(users);
832                                         g_object_unref(gus);
833                                         gus = NULL;
834                                         return -1;
835                                 }
836
837                                 snprintf(g_dir_engine_info, strlen(home_dir) + 34, "%s/share/.voice/tts/1.0/engine-info", home_dir);
838
839                                 md_iter = g_list_first(list);
840                                 while (NULL != md_iter) {
841                                         md = (metadata *)md_iter->data;
842                                         LOGD(" - key(%s) value(%s)", md->key, md->value);
843                                         md_iter = g_list_next(md_iter);
844                                 }
845
846                                 if (0 != __remove_engine_info_xml(pkgid, user_type, uid)) {
847                                         LOGE("[ERROR] Fail to remove engine info file");
848                                 }
849
850                                 free(home_dir);
851                                 home_dir = NULL;
852
853                                 free(g_dir_engine_info);
854                                 g_dir_engine_info = NULL;
855
856                                 g_free(user_type);
857
858                                 LOGD("Finish release memory");
859                                 iter = g_list_next(iter);
860                                 LOGD("Finish next iter");
861                         } else {
862                                 iter = g_list_next(iter);
863                         }
864                 }
865
866                 gum_user_service_list_free(users);
867                 g_object_unref(gus);
868                 gus = NULL;
869         } else {
870                 /* user directory */
871                 LOGD("[DEBUG] usertype: %s", g_user_type);
872
873                 ret = tzplatform_set_user(g_uid);
874                 if (ret < 0) {
875                         LOGE("[ERROR] Invalid uid");
876                         g_object_unref(g_guser);
877                         g_guser = NULL;
878                         g_free(g_user_type);
879                         return -1;
880                 } else {
881                         LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
882                         printf("[Parser Debug][DEBUG] TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
883                 }
884
885                 g_dir_engine_info = strdup(TTS_ENGINE_INFO);
886                 if (NULL == g_dir_engine_info) {
887                         LOGE("[ERROR] Fail to allocate memory");
888                         g_object_unref(g_guser);
889                         g_guser = NULL;
890                         g_free(g_user_type);
891                         return -1;
892                 }
893
894                 if (0 != __remove_engine_info_xml(pkgid, g_user_type, g_uid)) {
895                         LOGE("[ERROR] Fail to remove engine info file");
896                 }
897
898         }
899
900         if (NULL != g_guser) {
901                 g_object_unref(g_guser);
902                 g_guser = NULL;
903         }
904         g_free(g_user_type);
905
906         if (NULL != g_dir_engine_info) {
907                 free(g_dir_engine_info);
908                 g_dir_engine_info = NULL;
909         }
910
911         LOGD("");
912         return 0;
913 }
914
915 EXPORT_API
916 int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
917 {
918         LOGD("METADATA UPGRADE");
919         LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
920
921         PKGMGR_MDPARSER_PLUGIN_UNINSTALL(pkgid, appid, list);
922         PKGMGR_MDPARSER_PLUGIN_INSTALL(pkgid, appid, list);
923
924         LOGD("");
925         return 0;
926 }