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