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