Fix svace issues
[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
30 /* Define EXPORT_API */
31 #ifndef EXPORT_API
32 #define EXPORT_API __attribute__((visibility("default")))
33 #endif
34
35 #ifdef LOG_TAG
36 #undef LOG_TAG
37 #endif
38 #define LOG_TAG "stt-engine-parser"
39
40 #define STT_TAG_ENGINE_BASE                     "stt-engine"
41 #define STT_TAG_ENGINE_NAME                     "name"
42 #define STT_TAG_ENGINE_ID                       "id"
43 #define STT_TAG_ENGINE_SETTING                  "setting"
44 #define STT_TAG_ENGINE_LANGUAGE_SET             "languages"
45 #define STT_TAG_ENGINE_LANGUAGE                 "lang"
46 #define STT_TAG_ENGINE_SILENCE_DETECTION_SUPPORT        "silence-detection-support"
47 #define STT_TAG_ENGINE_CREDENTIAL               "credential"
48
49 #define STT_CONFIG_BASE         tzplatform_mkpath(TZ_USER_HOME, "share/.voice")
50 #define STT_HOME                tzplatform_mkpath(TZ_USER_HOME, "share/.voice/stt")
51 #define STT_ENGINE_BASE         tzplatform_mkpath(TZ_USER_HOME, "share/.voice/stt/1.0")
52 #define STT_ENGINE_INFO         tzplatform_mkpath(TZ_USER_HOME, "/share/.voice/stt/1.0/engine-info")
53
54 #define STT_METADATA_LANGUAGE                   "http://tizen.org/metadata/stt-engine/language"
55 #define STT_METADATA_SILENCE_DETECTION          "http://tizen.org/metadata/stt-engine/silence-detection"
56 #define STT_METADATA_CREDENTIAL_REQUIRED        "http://tizen.org/metadata/stt-engine/credential-required"
57
58 typedef struct metadata {
59         const char *key;
60         const char *value;
61 } metadata;
62
63 static xmlDocPtr g_doc;
64
65 static int __create_engine_info_xml(const char *pkgid)
66 {
67         LOGD("=== Create engine info doc");
68         g_doc = xmlNewDoc((xmlChar*)"1.0");
69         if (NULL == g_doc) {
70                 LOGE("[ERROR] Fail to new doc");
71                 return -1;
72         }
73         LOGD("===");
74         return 0;
75 }
76
77 static int __save_engine_info_xml(const char *pkgid)
78 {
79         LOGD("=== Save engine info doc");
80         /* Make directories */
81         if (0 != access(STT_CONFIG_BASE, F_OK)) {
82                 if (0 != mkdir(STT_CONFIG_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
83                         LOGE("[ERROR] Fail to make directory : %s", STT_CONFIG_BASE);
84                         return -1;
85                 } else {
86                         LOGD("Success to make directory : %s", STT_CONFIG_BASE);
87                 }
88         }
89
90         if (0 != access(STT_HOME, F_OK)) {
91                 if (0 != mkdir(STT_HOME, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
92                         LOGE("[ERROR] Fail to make directory : %s", STT_HOME);
93                         return -1;
94                 } else {
95                         LOGD("Success to make directory : %s", STT_HOME);
96                 }
97         }
98
99         if (0 != access(STT_ENGINE_BASE, F_OK)) {
100                 if (0 != mkdir(STT_ENGINE_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
101                         LOGE("[ERROR] Fail to make directory : %s", STT_ENGINE_BASE);
102                         return -1;
103                 } else {
104                         LOGD("Success to make directory : %s", STT_ENGINE_BASE);
105                 }
106         }
107
108         if (0 != access(STT_ENGINE_INFO, F_OK)) {
109                 if (0 != mkdir(STT_ENGINE_INFO, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
110                         LOGE("[ERROR] Fail to make directory : %s", STT_ENGINE_INFO);
111                         return -1;
112                 } else {
113                         LOGD("Success to make directory : %s", STT_ENGINE_INFO);
114                 }
115         }
116
117         char path[256] = {'\0',};
118         snprintf(path, 256, "%s/%s.xml", STT_ENGINE_INFO, pkgid);
119         int ret = xmlSaveFormatFile(path, g_doc, 1);
120         LOGD("xmlSaveFile (%d)", ret);
121         LOGD("===");
122         return 0;
123 }
124
125 static int __remove_engine_info_xml(const char *pkgid)
126 {
127         LOGD("=== Remove engine info doc");
128         char path[256] = {'\0',};
129         snprintf(path, 256, "%s/%s.xml", STT_ENGINE_INFO, pkgid);
130         if (0 == access(path, F_OK)) {
131                 LOGD("Remove engine info xml(%s)", path);
132                 if (0 != remove(path)) {
133                         LOGE("[ERROR] Fail to emove engine info xml(%s)", path);
134                 }
135         }
136         LOGD("===");
137         return 0;
138 }
139
140 static void __insert_language_from_metadata(xmlNodePtr root, const char *language)
141 {
142         LOGD("==== Insert language");
143         char* lang = NULL;
144
145         char *tmp_lang, *tmp_free;
146         tmp_free = tmp_lang = strdup(language);
147         xmlNodePtr languages_node = NULL;
148         xmlNodePtr lang_node = NULL;
149
150         languages_node = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_LANGUAGE_SET);
151
152         lang = strsep(&tmp_lang, ",");
153         while(NULL != lang) {
154                 LOGD("lang (%s)", lang);
155                 lang_node = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_LANGUAGE);
156                 xmlNodeSetContent(lang_node, (const xmlChar*)lang);
157                 xmlAddChild(languages_node, lang_node);
158                 lang = strsep(&tmp_lang, ",");
159         }
160         xmlAddChild(root, languages_node);
161
162         free(tmp_free);
163 }
164
165 EXPORT_API
166 int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
167 {
168         LOGD("METADATA INSTALL");
169         LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
170
171         uid_t uid = 0;
172         int ret = -1;
173         ret = pkgmgr_installer_info_get_target_uid(&uid);
174         if (ret < 0 ) {
175                 LOGE("[ERROR] Fail to get target uid");
176                 return 0;
177         } else {
178                 LOGD("uid(%d)", uid);
179         }
180
181         ret = tzplatform_set_user(uid);
182         if (ret < 0) {
183                 LOGE("[ERROR] Invalid uid");
184                 return 0;
185         } else {
186                 LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
187         }
188
189         if (0 >= g_list_length(list)) {
190                 LOGE("[ERROR] No Engine Metadata");
191                 return 0;
192         }
193
194         GList *iter = NULL;
195         metadata *md = NULL;
196
197         __create_engine_info_xml(pkgid);
198
199         xmlNodePtr root = NULL;
200         xmlNodePtr cur = NULL;
201
202         root = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_BASE);
203         if (NULL == root) {
204                 LOGE("[ERROR] Fail to get new node");
205                 xmlFreeDoc(g_doc);
206                 return -1;
207         }
208         xmlDocSetRootElement(g_doc, root);
209
210         /* Save name */
211         cur = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_NAME);
212         xmlNodeSetContent(cur, (const xmlChar*)pkgid);
213         xmlAddChild(root, cur);
214
215         iter = g_list_first(list);
216         while (NULL != iter) {
217                 md = (metadata *)iter->data;
218                 if (NULL != md && NULL != md->key && NULL != md->value) {
219                         LOGD(" - key(%s) value(%s)", md->key, md->value);
220                         if (!strcmp(md->key, STT_METADATA_LANGUAGE)) {
221                                 __insert_language_from_metadata(root, md->value);
222                         } else if (!strcmp(md->key, STT_METADATA_SILENCE_DETECTION)) {
223                                 cur = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_SILENCE_DETECTION_SUPPORT);
224                                 xmlNodeSetContent(cur, (const xmlChar*)md->value);
225                                 xmlAddChild(root, cur);
226                         } else if (!strcmp(md->key, STT_METADATA_CREDENTIAL_REQUIRED)) {
227                                 cur = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_CREDENTIAL);
228                                 xmlNodeSetContent(cur, (const xmlChar*)md->value);
229                                 xmlAddChild(root, cur);
230                         } else {
231                                 LOGW("[WARNING] Unknown metadata type");
232                         }
233                 }
234                 iter = g_list_next(iter);
235         }
236
237         cur = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_ID);
238         xmlNodeSetContent(cur, (const xmlChar*)appid);
239         xmlAddChild(root, cur);
240
241         LOGD("");
242
243         if (0 != __save_engine_info_xml(pkgid)) {
244                 LOGE("[ERROR] Fail to make engine info file");
245                 return -1;
246         }
247
248         xmlFreeDoc(g_doc);
249
250         return 0;
251 }
252
253 EXPORT_API
254 int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
255 {
256         LOGD("METADATA UNINSTALL");
257         LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
258
259         GList *iter = NULL;
260         metadata *md = NULL;
261
262         iter = g_list_first(list);
263         while (NULL != iter) {
264                 md = (metadata *)iter->data;
265                 LOGD(" - key(%s) value(%s)", md->key, md->value);
266                 iter = g_list_next(iter);
267         }
268
269         __remove_engine_info_xml(pkgid);
270
271         LOGD("");
272         return 0;
273 }
274
275 EXPORT_API
276 int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
277 {
278         LOGD("METADATA UPGRADE");
279         LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
280
281         PKGMGR_MDPARSER_PLUGIN_UNINSTALL(pkgid, appid, list);
282         PKGMGR_MDPARSER_PLUGIN_INSTALL(pkgid, appid, list);
283
284         LOGD("");
285         return 0;
286 }