feedback: Change feedback pattern data from list to GHashTable
[platform/core/system/libsvi.git] / src / sound-parser.c
1 /*
2  * libfeedback
3  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <glib.h>
19 #include <stdbool.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <unistd.h>
23
24 #include <libsyscommon/ini-parser.h>
25 #include <libsyscommon/list.h>
26
27 #include "log.h"
28 #include "profiles.h"
29 #include "sound-theme-manager.h"
30
31 #define INITIAL_DEFAULT_SOUND_THEME_ID                          -1
32 #define SOUND_CONF_FILE FEEDBACK_SYS_RO_SHARE"/feedback/sound.conf"
33
34 static int default_sound_theme_id = INITIAL_DEFAULT_SOUND_THEME_ID;
35
36 struct sound_theme_info {
37         int id;
38         int is_default;
39         char *conf_file_path;
40 };
41
42 static void destroy_hash_table(void *hash_table)
43 {
44         if (hash_table)
45                 g_hash_table_destroy(g_steal_pointer((GHashTable**)hash_table));
46 }
47
48 static bool is_sound_theme_id_duplicated(int sound_theme_id, void *data)
49 {
50         GHashTable *hash_table_to_check_id_duplicated = (GHashTable *)data;
51         gint *hash_key = g_new(gint, 1);
52         *hash_key = sound_theme_id;
53         if (g_hash_table_contains(hash_table_to_check_id_duplicated, hash_key)) {
54                 g_free(hash_key);
55                 return true;
56         }
57
58         g_hash_table_insert(hash_table_to_check_id_duplicated, hash_key, NULL);
59         return false;
60 }
61
62 static bool is_default_theme_id_set(void)
63 {
64         if (default_sound_theme_id == INITIAL_DEFAULT_SOUND_THEME_ID)
65                 return false;
66         return true;
67 }
68
69 static int parse_sound_theme_property(gpointer data, gpointer user_data)
70 {
71         struct section_property *prop = (struct section_property *) data;
72         struct sound_theme_info *sound_theme_elem = (struct sound_theme_info *)user_data;
73
74         if (!prop || !sound_theme_elem)
75                 return 0;
76
77         if (MATCH(prop->key, "SoundThemeId")) {
78                 sscanf(prop->value, "%d", (&sound_theme_elem->id));
79                 if (sound_theme_elem->id < 0)
80                         return -EPERM;
81         } else if (MATCH(prop->key, "SoundThemePath")) {
82                 int str_len = sizeof(prop->value);
83                 sound_theme_elem->conf_file_path = strndup(prop->value, str_len);
84         } else if (MATCH(prop->key, "SoundThemeDefault")) {
85                 if (MATCH(prop->value, "yes"))
86                         sound_theme_elem->is_default = 1;
87                 else if (MATCH(prop->value, "no"))
88                         sound_theme_elem->is_default = 0;
89                 else
90                         return -EPERM;
91         }
92         return 0;
93 }
94
95
96 static int parse_sound_theme_section(const struct parse_result *result, void *data)
97 {
98         struct sound_theme_info sound_theme_elem = {
99                 .id = 0,
100                 .is_default = 0,
101                 .conf_file_path = NULL
102         };
103         struct section_property *extracted_section_prop = NULL;
104         GList *temp_glist = NULL;
105         int ret = 0;
106
107         if (!result || !result->props)
108                 return 0;
109
110         if (!MATCH("SoundTheme", result->section))
111                 return 0;
112
113         SYS_G_LIST_FOREACH(result->props, temp_glist, extracted_section_prop) {
114                 if (parse_sound_theme_property(extracted_section_prop, &sound_theme_elem) < 0)
115                         goto out_parsing_fail;
116         }
117
118         if (is_sound_theme_id_duplicated(sound_theme_elem.id, data)) {
119                 _E("Failed to parse sound conf file, sound theme id is duplicated.");
120                 goto out_parsing_fail;
121         }
122
123         if (sound_theme_elem.is_default) {
124                 if (is_default_theme_id_set()) {
125                         _E("Failed to parse sound conf file, default sound theme is duplicated.");
126                         goto out_parsing_fail;
127                 }
128                 default_sound_theme_id = sound_theme_elem.id;
129                 sound_thememan_set_default_sound_theme_id(default_sound_theme_id);
130         }
131
132         ret = sound_thememan_add_sound_theme(sound_theme_elem.id, sound_theme_elem.conf_file_path);
133         free(sound_theme_elem.conf_file_path);
134
135         if (ret < 0)
136                 return ret;
137
138         return 0;
139
140 out_parsing_fail:
141         _E("Failed to parse sound conf file, please check conf file description and follow the rules");
142         free(sound_theme_elem.conf_file_path);
143
144         return -EPERM;
145 }
146
147 static int parse_sound_section(const struct parse_result *result, void *data)
148 {
149         if (!result || !result->props)
150                 return 0;
151
152         if (MATCH(result->section, "Sound")) {
153                 if (is_default_theme_id_set()) {
154                         _E("Failed to parse sound conf file, please check conf file description and follow the rules");
155                         return -EINVAL;
156                 }
157                 default_sound_theme_id = 0;
158                 sound_thememan_add_sound_theme(default_sound_theme_id, SOUND_CONF_FILE);
159                 return 0;
160         }
161
162         return 0;
163 }
164
165 int sound_parser_init(void)
166 {
167         int ret = 0;
168         GHashTable *hash_table_to_check_id_duplicated;
169
170         ret = syscommon_config_parse_by_section(SOUND_CONF_FILE, parse_sound_section, NULL);
171         if (ret < 0) {
172                 _E("Failed to parse sound conf file. [Sound] section parsing failed.");
173                 return ret;
174         }
175
176         if (is_default_theme_id_set())
177                 return 0;
178
179         hash_table_to_check_id_duplicated = g_hash_table_new_full(g_int_hash, g_int_equal,
180                                                                         g_free, g_free);
181         ret = syscommon_config_parse_by_section(SOUND_CONF_FILE, parse_sound_theme_section, hash_table_to_check_id_duplicated);
182         if (ret < 0) {
183                 _E("Failed to parse sound conf file. [SoundTheme] section parsing failed.");
184                 goto destroy_hash_table;
185         }
186
187         if (!is_default_theme_id_set()) {
188                 _E("Failed to parse sound conf file. There is no default sound theme id");
189                 ret = -EPERM;
190                 goto destroy_hash_table;
191         }
192
193 destroy_hash_table:
194         destroy_hash_table(&hash_table_to_check_id_duplicated);
195
196         return ret;
197 }
198
199 void sound_parser_exit(void)
200 {
201         default_sound_theme_id = INITIAL_DEFAULT_SOUND_THEME_ID;
202 }
203
204 static int parse_sound_property(const struct parse_result *result, void *data)
205 {
206         struct section_property *extracted_section_prop = NULL;
207         GList *temp_glist = NULL;
208         int pattern = 0;
209         GHashTable *sound_config_info;
210
211         if (!result || !result->props)
212                 return 0;
213
214         if (!data)
215                 return -EINVAL;
216
217         if (!MATCH(result->section, "Sound"))
218                 return 0;
219
220         sound_config_info = (GHashTable*)data;
221
222         SYS_G_LIST_FOREACH(result->props, temp_glist, extracted_section_prop) {
223                 pattern = profile->get_pattern_enum(extracted_section_prop->key);
224                 if (pattern < 0 || pattern >= profile->max_pattern)
225                         return -EINVAL;
226                 g_hash_table_insert(sound_config_info, GINT_TO_POINTER(pattern),
227                                         g_strdup(extracted_section_prop->value));
228         }
229         return 0;
230 }
231
232 int sound_parser_get_config_info(const char *file_path, void *config_info)
233 {
234         int ret = 0;
235         GHashTable *sound_info;
236
237         if (!file_path || !config_info)
238                 return -EINVAL;
239
240         sound_info = (GHashTable*)config_info;
241         ret = syscommon_config_parse_by_section(file_path, parse_sound_property, sound_info);
242         if (ret < 0) {
243                 _E("Failed to parse sound conf feedback pattern.");
244                 return -EPERM;
245         }
246
247         return 0;
248 }