Update hello protocol
[platform/core/uifw/tts.git] / engine-parser / src / tts-engine-language-pack-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 <sys/stat.h>
25 #include <sys/types.h>
26 #include <tzplatform_config.h>
27
28 /* Define EXPORT_API */
29 #ifndef EXPORT_API
30 #define EXPORT_API __attribute__((visibility("default")))
31 #endif
32
33 #ifdef LOG_TAG
34 #undef LOG_TAG
35 #endif
36 #define LOG_TAG "tts-engine-parser"
37
38 #define TTS_TAG_ENGINE_LANG_BASE                "tts-engine-language-pack"
39 #define TTS_TAG_ENGINE_NAME                     "name"
40 #define TTS_TAG_ENGINE_ID                       "id"
41 #define TTS_TAG_ENGINE_VOICE_SET                "voices"
42 #define TTS_TAG_ENGINE_VOICE                    "voice"
43 #define TTS_TAG_ENGINE_VOICE_TYPE               "type"
44
45 #define TTS_CONFIG_BASE         tzplatform_mkpath(TZ_USER_HOME, "share/.voice")
46 #define TTS_HOME                tzplatform_mkpath(TZ_USER_HOME, "share/.voice/tts")
47 #define TTS_ENGINE_BASE         tzplatform_mkpath(TZ_USER_HOME, "share/.voice/tts/1.0")
48 #define TTS_ENGINE_INFO         tzplatform_mkpath(TZ_USER_SHARE, ".voice/tts/1.0/engine-info")
49
50 #define TTS_METADATA_LANGUAGE   "http://tizen.org/metadata/tts-engine-language-pack/language"
51
52 typedef struct metadata {
53         const char *key;
54         const char *value;
55 } metadata;
56
57 static xmlDocPtr g_doc;
58
59 static int __create_engine_info_xml(const char *pkgid)
60 {
61         LOGD("=== Create engine info doc");
62         g_doc = xmlNewDoc((xmlChar*)"1.0");
63         if (NULL == g_doc) {
64                 LOGE("[ERROR] Fail to new doc");
65                 return -1;
66         }
67         LOGD("===");
68         return 0;
69 }
70
71 static int __save_engine_info_xml(const char *pkgid)
72 {
73         LOGD("=== Save engine info doc");
74
75         /* Make directories */
76         if (0 != access(TTS_CONFIG_BASE, F_OK)) {
77                 if (0 != mkdir(TTS_CONFIG_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
78                         LOGE("[ERROR] Fail to make directory : %s", TTS_CONFIG_BASE);
79                         return -1;
80                 } else {
81                         LOGD("Success to make directory : %s", TTS_CONFIG_BASE);
82                 }
83         }
84
85         if (0 != access(TTS_HOME, F_OK)) {
86                 if (0 != mkdir(TTS_HOME, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
87                         LOGE("[ERROR] Fail to make directory : %s", TTS_HOME);
88                         return -1;
89                 } else {
90                         LOGD("Success to make directory : %s", TTS_HOME);
91                 }
92         }
93
94         if (0 != access(TTS_ENGINE_BASE, F_OK)) {
95                 if (0 != mkdir(TTS_ENGINE_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
96                         LOGE("[ERROR] Fail to make directory : %s", TTS_ENGINE_BASE);
97                         return -1;
98                 } else {
99                         LOGD("Success to make directory : %s", TTS_ENGINE_BASE);
100                 }
101         }
102
103         if (0 != access(TTS_ENGINE_INFO, F_OK)) {
104                 if (0 != mkdir(TTS_ENGINE_INFO, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
105                         LOGE("[ERROR] Fail to make directory : %s", TTS_ENGINE_INFO);
106                         return -1;
107                 } else {
108                         LOGD("Success to make directory : %s", TTS_ENGINE_INFO);
109                 }
110         }
111
112         char path[256] = {'\0',};
113         snprintf(path, 256, "%s/%s.xml", TTS_ENGINE_INFO, pkgid);
114         int ret = xmlSaveFormatFile(path, g_doc, 1);
115         LOGD("xmlSaveFile (%d)", ret);
116         LOGD("===");
117         return 0;
118 }
119
120 static int __remove_engine_info_xml(const char *pkgid)
121 {
122         LOGD("=== Remove engine info doc");
123         char path[256] = {'\0',};
124         snprintf(path, 256, "%s/%s.xml", TTS_ENGINE_INFO, pkgid);
125         if (0 == access(path, F_OK)) {
126                 LOGD("Remove engine info xml(%s)", path);
127                 remove(path);
128         }
129         LOGD("===");
130         return 0;
131 }
132
133 static void __insert_language_from_metadata(xmlNodePtr root, const char *language)
134 {
135         LOGD("==== Insert language");
136         char* voice = NULL;
137         char* lang = NULL;
138         char* type = NULL;
139
140         char *tmp_lang = NULL;
141         char *tmp_free = NULL;
142         tmp_free = tmp_lang = strdup(language);
143         if (NULL == tmp_lang) {
144                 LOGE("Fail to memory allocation");
145                 return;
146         }
147         xmlNodePtr voices_node = NULL;
148         xmlNodePtr voice_node = NULL;
149
150         voices_node = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_VOICE_SET);
151
152         voice = strsep(&tmp_lang, ",");
153         while (NULL != voice) {
154                 LOGD("voice (%s)", voice);
155                 voice_node = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_VOICE);
156                 lang = strsep(&voice, ":");
157                 LOGD("lang (%s)", lang);
158                 type = strsep(&voice, " ");
159                 LOGD("type (%s)", type);
160                 xmlSetProp(voice_node, (const xmlChar*)TTS_TAG_ENGINE_VOICE_TYPE, (const xmlChar*)type);
161                 xmlNodeSetContent(voice_node, (const xmlChar*)lang);
162                 xmlAddChild(voices_node, voice_node);
163                 voice = strsep(&tmp_lang, ",");
164         }
165         xmlAddChild(root, voices_node);
166
167         free(tmp_free);
168         tmp_free = NULL;
169 }
170
171 EXPORT_API
172 int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
173 {
174         LOGD("METADATA INSTALL");
175         LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
176
177         if (0 >= g_list_length(list)) {
178                 LOGE("[ERROR] No Engine Metadata");
179                 return 0;
180         }
181
182         GList *iter = NULL;
183         metadata *md = NULL;
184
185         __create_engine_info_xml(pkgid);
186
187         xmlNodePtr root = NULL;
188         xmlNodePtr cur = NULL;
189
190         root = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_LANG_BASE);
191         if (NULL == root) {
192                 LOGE("[ERROR] Fail to get new node");
193                 xmlFreeDoc(g_doc);
194                 return -1;
195         }
196         xmlDocSetRootElement(g_doc, root);
197
198         /* Save name */
199         cur = xmlNewNode(NULL, (const xmlChar*)TTS_TAG_ENGINE_NAME);
200         xmlNodeSetContent(cur, (const xmlChar*)pkgid);
201         xmlAddChild(root, cur);
202
203         iter = g_list_first(list);
204         while (NULL != iter) {
205                 md = (metadata *)iter->data;
206                 if (NULL != md && NULL != md->key) {
207                         LOGD(" - key(%s) value(%s)", md->key, md->value);
208                         if (!strcmp(md->key, TTS_METADATA_LANGUAGE)) {
209                                 __insert_language_from_metadata(root, md->value);
210                         } else {
211                                 LOGW("[WARNING] Unknown metadata type");
212                         }
213                 }
214                 iter = g_list_next(iter);
215         }
216
217         LOGD("");
218
219         __save_engine_info_xml(pkgid);
220         xmlFreeDoc(g_doc);
221
222         return 0;
223 }
224
225 EXPORT_API
226 int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
227 {
228         LOGD("METADATA UNINSTALL");
229         LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
230
231         GList *iter = NULL;
232         metadata *md = NULL;
233
234         iter = g_list_first(list);
235         while (NULL != iter) {
236                 md = (metadata *)iter->data;
237                 if (NULL != md && NULL != md->key) {
238                         LOGD(" - key(%s) value(%s)", md->key, md->value);
239                 }
240                 iter = g_list_next(iter);
241         }
242
243         __remove_engine_info_xml(pkgid);
244
245         LOGD("");
246         return 0;
247 }
248
249 EXPORT_API
250 int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
251 {
252         LOGD("METADATA UPGRADE");
253         LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list));
254
255         PKGMGR_MDPARSER_PLUGIN_UNINSTALL(pkgid, appid, list);
256         PKGMGR_MDPARSER_PLUGIN_INSTALL(pkgid, appid, list);
257
258         LOGD("");
259         return 0;
260 }