Fix svace issues
[platform/core/uifw/tts.git] / engine-parser / src / tts-engine-parser.c
1 //
2 // Copyright (c) 2016 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include <app_manager.h>
18 #include <dlog.h>
19 #include <errno.h>
20 #include <glib.h>
21 #include <libxml/parser.h>
22 #include <libxml/tree.h>
23 #include <pkgmgr-info.h>
24 #include <pkgmgr_installer_info.h>
25 #include <stdio.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <tzplatform_config.h>
29
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 "tts-engine-parser"
39
40 #define TTS_TAG_ENGINE_BASE                     "tts-engine"
41 #define TTS_TAG_ENGINE_NAME                     "name"
42 #define TTS_TAG_ENGINE_ID                       "id"
43 #define TTS_TAG_ENGINE_SETTING                  "setting"
44 #define TTS_TAG_ENGINE_VOICE_SET                "voices"
45 #define TTS_TAG_ENGINE_VOICE                    "voice"
46 #define TTS_TAG_ENGINE_VOICE_TYPE               "type"
47 #define TTS_TAG_ENGINE_PITCH_SUPPORT            "pitch-support"
48 #define TTS_TAG_ENGINE_CREDENTIAL               "credential"
49
50 #define TTS_CONFIG_BASE         tzplatform_mkpath(TZ_USER_HOME, "share/.voice")
51 #define TTS_HOME                tzplatform_mkpath(TZ_USER_HOME, "share/.voice/tts")
52 #define TTS_ENGINE_BASE         tzplatform_mkpath(TZ_USER_HOME, "share/.voice/tts/1.0")
53 #define TTS_ENGINE_INFO         tzplatform_mkpath(TZ_USER_SHARE, ".voice/tts/1.0/engine-info")
54
55 #define TTS_METADATA_LANGUAGE                   "http://tizen.org/metadata/tts-engine/language"
56 #define TTS_METADATA_CREDENTIAL_REQUIRED        "http://tizen.org/metadata/tts-engine/credential-required"
57
58
59 typedef struct metadata {
60         const char *key;
61         const char *value;
62 } metadata;
63
64 static xmlDocPtr g_doc;
65
66 static int __create_engine_info_xml(const char *pkgid)
67 {
68         LOGD("=== Create engine info doc");
69         g_doc = xmlNewDoc((xmlChar*)"1.0");
70         if (NULL == g_doc) {
71                 LOGE("[ERROR] Fail to new doc");
72                 return -1;
73         }
74         LOGD("===");
75         return 0;
76 }
77
78 static int __save_engine_info_xml(const char *pkgid)
79 {
80         LOGD("=== Save engine info doc");
81
82         /* Make directories */
83         if (0 != access(TTS_CONFIG_BASE, F_OK)) {
84                 if (0 != mkdir(TTS_CONFIG_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
85                         LOGE("[ERROR] Fail to make directory : %s", TTS_CONFIG_BASE);
86                         return -1;
87                 } else {
88                         LOGD("Success to make directory : %s", TTS_CONFIG_BASE);
89                 }
90         }
91
92         if (0 != access(TTS_HOME, F_OK)) {
93                 if (0 != mkdir(TTS_HOME, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
94                         LOGE("[ERROR] Fail to make directory : %s", TTS_HOME);
95                         return -1;
96                 } else {
97                         LOGD("Success to make directory : %s", TTS_HOME);
98                 }
99         }
100
101         if (0 != access(TTS_ENGINE_BASE, F_OK)) {
102                 if (0 != mkdir(TTS_ENGINE_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
103                         LOGE("[ERROR] Fail to make directory : %s", TTS_ENGINE_BASE);
104                         return -1;
105                 } else {
106                         LOGD("Success to make directory : %s", TTS_ENGINE_BASE);
107                 }
108         }
109
110         if (0 != access(TTS_ENGINE_INFO, F_OK)) {
111                 if (0 != mkdir(TTS_ENGINE_INFO, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
112                         LOGE("[ERROR] Fail to make directory : %s", TTS_ENGINE_INFO);
113                         return -1;
114                 } else {
115                         LOGD("Success to make directory : %s", TTS_ENGINE_INFO);
116                 }
117         }
118
119         char path[256] = {'\0',};
120         snprintf(path, 256, "%s/%s.xml", TTS_ENGINE_INFO, pkgid);
121         int ret = xmlSaveFormatFile(path, g_doc, 1);
122         LOGD("xmlSaveFile (%d)", ret);
123         LOGD("===");
124         return 0;
125 }
126
127 static int __remove_engine_info_xml(const char *pkgid)
128 {
129         LOGD("=== Remove engine info doc");
130         char path[256] = {'\0',};
131         snprintf(path, 256, "%s/%s.xml", TTS_ENGINE_INFO, pkgid);
132         if (0 == access(path, F_OK)) {
133                 LOGD("Remove engine info xml(%s)", path);
134                 if (0 != remove(path)) {
135                         LOGE("[ERROR] Fail to Remove engine info xml(%s)", path);
136                 }
137         }
138         LOGD("===");
139         return 0;
140 }
141
142 static void __insert_language_from_metadata(xmlNodePtr root, const char *language)
143 {
144         LOGD("==== Insert language");
145         char* voice = NULL;
146         char* lang = NULL;
147         char* type = NULL;
148
149         char *tmp_lang = NULL;
150         char *tmp_free = NULL;
151         tmp_free = tmp_lang = strdup(language);
152         if (NULL != tmp_lang) {
153                 LOGE("Fail to memory allocation");
154                 return;
155         }
156         xmlNodePtr voices_node = NULL;
157         xmlNodePtr voice_node = NULL;
158
159         voices_node = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_VOICE_SET);
160
161         voice = strsep(&tmp_lang, ",");
162         while(NULL != voice) {
163                 LOGD("voice (%s)", voice);
164                 voice_node = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_VOICE);
165                 lang = strsep(&voice, ":");
166                 LOGD("lang (%s)", lang);
167                 type = strsep(&voice, " ");
168                 LOGD("type (%s)", type);
169                 xmlSetProp(voice_node, (const xmlChar*)TTS_TAG_ENGINE_VOICE_TYPE, (const xmlChar*)type);
170                 xmlNodeSetContent(voice_node, (const xmlChar*)lang);
171                 xmlAddChild(voices_node, voice_node);
172                 voice = strsep(&tmp_lang, ",");
173         }
174         xmlAddChild(root, voices_node);
175
176         free(tmp_free);
177         tmp_free = NULL;
178 }
179
180 EXPORT_API
181 int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
182 {
183         LOGD("METADATA INSTALL");
184         LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
185
186         uid_t uid = 0;
187         int ret = -1;
188         ret = pkgmgr_installer_info_get_target_uid(&uid);
189         if (ret < 0 ) {
190                 LOGE("[ERROR] Fail to get target uid");
191                 return 0;
192         } else {
193                 LOGD("uid(%d)", uid);
194         }
195
196         ret = tzplatform_set_user(uid);
197         if (ret < 0) {
198                 LOGE("[ERROR] Invalid uid");
199                 return 0;
200         } else {
201                 LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/"));
202         }
203
204         if (0 >= g_list_length(list)) {
205                 LOGE("[ERROR] No Engine Metadata");
206                 return 0;
207         }
208
209         GList *iter = NULL;
210         metadata *md = NULL;
211
212         __create_engine_info_xml(pkgid);
213
214         xmlNodePtr root = NULL;
215         xmlNodePtr cur = NULL;
216
217         root = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_BASE);
218         if (NULL == root) {
219                 LOGE("[ERROR] Fail to get new node");
220                 xmlFreeDoc(g_doc);
221                 return -1;
222         }
223         xmlDocSetRootElement(g_doc, root);
224
225         /* Save name */
226         cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_NAME);
227         xmlNodeSetContent(cur, (const xmlChar*)pkgid);
228         xmlAddChild(root, cur);
229
230         iter = g_list_first(list);
231         while (NULL != iter) {
232                 md = (metadata *)iter->data;
233                 if (NULL != md && NULL != md->key) {
234                         LOGD(" - key(%s) value(%s)", md->key, md->value);
235                         if (!strcmp(md->key, TTS_METADATA_LANGUAGE)) {
236                                 __insert_language_from_metadata(root, md->value);
237                         } else if (!strcmp(md->key, TTS_METADATA_CREDENTIAL_REQUIRED)) {
238                                 cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_CREDENTIAL);
239                                 xmlNodeSetContent(cur, (const xmlChar*)md->value);
240                                 xmlAddChild(root, cur);
241                         } else {
242                                 LOGW("[WARNING] Unknown metadata type");
243                         }
244                 }
245                 iter = g_list_next(iter);
246         }
247
248         cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_ID);
249         xmlNodeSetContent(cur, (const xmlChar*)pkgid);
250         xmlAddChild(root, cur);
251
252         LOGD("");
253
254         __save_engine_info_xml(pkgid);
255         xmlFreeDoc(g_doc);
256
257         return 0;
258 }
259
260 EXPORT_API
261 int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
262 {
263         LOGD("METADATA UNINSTALL");
264         LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
265
266         GList *iter = NULL;
267         metadata *md = NULL;
268
269         iter = g_list_first(list);
270         while (NULL != iter) {
271                 md = (metadata *)iter->data;
272                 if (NULL != md && NULL != md->key) {
273                         LOGD(" - key(%s) value(%s)", md->key, md->value);
274                 }
275                 iter = g_list_next(iter);
276         }
277
278         __remove_engine_info_xml(pkgid);
279
280         LOGD("");
281         return 0;
282 }
283
284 EXPORT_API
285 int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
286 {
287         LOGD("METADATA UPGRADE");
288         LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
289
290         PKGMGR_MDPARSER_PLUGIN_UNINSTALL(pkgid, appid, list);
291         PKGMGR_MDPARSER_PLUGIN_INSTALL(pkgid, appid, list);
292
293         LOGD("");
294         return 0;
295 }