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