2 * Copyright (c) 2011-2020 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include "sst_vconf.h"
26 #include "sst_interface.h"
28 static GHashTable *sst_vconf_map_org = NULL;
29 static GHashTable *sst_vconf_map = NULL;
31 struct sst_vconf_info_s {
32 system_settings_key_e key;
33 system_settings_changed_cb cb;
37 int sst_vconf_set_int(sst_interface *iface, int val)
39 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
40 RETV_IF(NULL == iface->vconf_key, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
42 if (VCONF_OK != vconf_set_int(iface->vconf_key, val)) {
43 ERR("vconf_set_int(%s, %d) Fail", iface->vconf_key, val);
44 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
47 return SYSTEM_SETTINGS_ERROR_NONE;
50 int sst_vconf_set_bool(sst_interface *iface, bool val)
52 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
53 RETV_IF(NULL == iface->vconf_key, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
55 if (VCONF_OK != vconf_set_bool(iface->vconf_key, val)) {
56 ERR("vconf_set_bool(%s, %d) Fail", iface->vconf_key, val);
57 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
60 return SYSTEM_SETTINGS_ERROR_NONE;
63 int sst_vconf_set_str(sst_interface *iface, const char *val)
65 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
66 RETV_IF(NULL == iface->vconf_key, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
68 if (VCONF_OK != vconf_set_str(iface->vconf_key, val)) {
69 ERR("vconf_set_str(%s, %s) Fail", iface->vconf_key, val);
70 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
73 return SYSTEM_SETTINGS_ERROR_NONE;
76 int sst_vconf_get_int(sst_interface *iface, int *val)
78 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
79 RETV_IF(NULL == iface->vconf_key, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
82 if (VCONF_OK != vconf_get_int(iface->vconf_key, &result)) {
83 ERR("vconf_get_int(%s) Fail", iface->vconf_key);
84 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
87 *val = result ? true : false;
89 return SYSTEM_SETTINGS_ERROR_NONE;
92 int sst_vconf_get_bool(sst_interface *iface, bool *val)
94 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
95 RETV_IF(NULL == iface->vconf_key, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
98 if (VCONF_OK != vconf_get_bool(iface->vconf_key, &result)) {
99 ERR("vconf_get_bool(%s) Fail", iface->vconf_key);
100 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
103 *val = result ? true : false;
105 return SYSTEM_SETTINGS_ERROR_NONE;
108 int sst_vconf_get_str(sst_interface *iface, char **val)
110 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
111 RETV_IF(NULL == iface->vconf_key, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
113 char *result = vconf_get_str(iface->vconf_key);
114 if (NULL == result) {
115 ERR("vconf_get_str(%s) Fail(NULL)", iface->vconf_key);
116 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
120 return SYSTEM_SETTINGS_ERROR_NONE;
123 int sst_vconf_get_str_ally(const char *vconf_key, char **value)
125 char *str_value = vconf_get_str(vconf_key);
126 if (NULL == str_value) {
127 ERR("vconf_get_str(%s) Fail(NULL)", vconf_key);
128 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
132 return SYSTEM_SETTINGS_ERROR_NONE;
135 static inline GHashTable* _map_erase(GHashTable *hash_table, const char *key)
137 g_hash_table_remove(hash_table, key);
138 if (0 == g_hash_table_size(hash_table)) {
139 g_hash_table_unref(hash_table);
145 static void _callback_fn_org(keynode_t *node, void *user_data)
147 RET_IF(NULL == sst_vconf_map_org);
149 GList *list = g_hash_table_lookup(sst_vconf_map_org, node->keyname);
151 for (it = list; it; it = it->next) {
152 struct sst_vconf_info_s *info = it->data;
153 if (info && info->cb)
154 info->cb(info->key, info->cb_data);
158 static gint _compare_key(gconstpointer a, gconstpointer b)
160 const struct sst_vconf_info_s *info = a;
162 RETV_IF(NULL == a, 1);
164 if (info->key == GPOINTER_TO_INT(b))
170 int sst_vconf_set_cb(sst_interface *iface, system_settings_changed_cb cb, void *user_data)
174 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
175 RETV_IF(NULL == cb, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
177 if (sst_vconf_map_org) {
178 list = g_hash_table_lookup(sst_vconf_map_org, iface->vconf_key);
179 GList *found = g_list_find_custom(list, GINT_TO_POINTER(iface->key), _compare_key);
181 ERR("callback Already Exist");
182 return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
185 sst_vconf_map_org = g_hash_table_new(g_str_hash, g_str_equal);
188 struct sst_vconf_info_s *info = malloc(sizeof(struct sst_vconf_info_s));
190 ERR("malloc() Fail(%d)", errno);
191 return SYSTEM_SETTINGS_ERROR_OUT_OF_MEMORY;
193 info->key = iface->key;
195 info->cb_data = user_data;
197 GList *new_list = g_list_append(list, info);
198 g_hash_table_replace(sst_vconf_map_org, (char*)iface->vconf_key, new_list);
201 int ret = vconf_notify_key_changed(iface->vconf_key, _callback_fn_org, NULL);
202 if (VCONF_OK != ret) {
203 ERR("vconf_notify_key_changed(%s) Fail", iface->vconf_key);
204 new_list = g_list_remove(new_list, info);
205 if (NULL == new_list)
206 sst_vconf_map_org = _map_erase(sst_vconf_map_org, iface->vconf_key);
208 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
212 return SYSTEM_SETTINGS_ERROR_NONE;
215 int sst_vconf_unset_cb(sst_interface *iface)
217 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
218 RETV_IF(NULL == sst_vconf_map_org, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
220 GList *list = g_hash_table_lookup(sst_vconf_map_org, iface->vconf_key);
221 GList *found = g_list_find_custom(list, GINT_TO_POINTER(iface->key), _compare_key);
224 return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
227 if (1 == g_list_length(list)) {
228 int ret = vconf_ignore_key_changed(iface->vconf_key, _callback_fn_org);
229 if (VCONF_OK != ret) {
230 ERR("vconf_ignore_key_changed(%s) Fail", iface->vconf_key);
231 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
235 list = g_list_remove_link(list, found);
237 g_hash_table_replace(sst_vconf_map_org, (char*)iface->vconf_key, list);
239 sst_vconf_map_org = _map_erase(sst_vconf_map_org, iface->vconf_key);
244 return SYSTEM_SETTINGS_ERROR_NONE;
247 static void _callback_fn(keynode_t *node, void *user_data)
249 RET_IF(NULL == sst_vconf_map);
251 GList *list = g_hash_table_lookup(sst_vconf_map, node->keyname);
253 for (it = list; it; it = it->next) {
254 struct sst_vconf_info_s *info = it->data;
255 if (info && info->cb)
256 info->cb(info->key, info->cb_data);
260 static gint _compare_cb(gconstpointer a, gconstpointer b)
262 const struct sst_vconf_info_s *info = a;
264 RETV_IF(NULL == a, 1);
265 RETV_IF(NULL == b, 1);
273 int sst_vconf_add_multi_cb(sst_interface *iface, system_settings_changed_cb cb, void *user_data)
277 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
278 RETV_IF(NULL == cb, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
281 list = g_hash_table_lookup(sst_vconf_map, iface->vconf_key);
282 GList *found = g_list_find_custom(list, cb, _compare_cb);
284 ERR("callback Already Exist");
285 return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
288 sst_vconf_map = g_hash_table_new(g_str_hash, g_str_equal);
291 struct sst_vconf_info_s *info = malloc(sizeof(struct sst_vconf_info_s));
293 ERR("malloc() Fail(%d)", errno);
294 return SYSTEM_SETTINGS_ERROR_OUT_OF_MEMORY;
296 info->key = iface->key;
298 info->cb_data = user_data;
300 GList *new_list = g_list_append(list, info);
301 g_hash_table_replace(sst_vconf_map, (char*)iface->vconf_key, new_list);
304 int ret = vconf_notify_key_changed(iface->vconf_key, _callback_fn, NULL);
305 if (VCONF_OK != ret) {
306 ERR("vconf_notify_key_changed(%s) Fail", iface->vconf_key);
307 new_list = g_list_remove(new_list, info);
308 if (NULL == new_list)
309 sst_vconf_map = _map_erase(sst_vconf_map, iface->vconf_key);
311 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
315 return SYSTEM_SETTINGS_ERROR_NONE;
318 int sst_vconf_del_multi_cb(sst_interface *iface, system_settings_changed_cb cb)
320 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
321 RETV_IF(NULL == cb, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
322 RETV_IF(NULL == sst_vconf_map, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
324 GList *list = g_hash_table_lookup(sst_vconf_map, iface->vconf_key);
325 GList *found = g_list_find_custom(list, cb, _compare_cb);
328 return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
331 if (1 == g_list_length(list)) {
332 int ret = vconf_ignore_key_changed(iface->vconf_key, _callback_fn);
333 if (VCONF_OK != ret) {
334 ERR("vconf_ignore_key_changed(%s) Fail", iface->vconf_key);
335 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
339 list = g_list_remove_link(list, found);
341 g_hash_table_replace(sst_vconf_map, (char*)iface->vconf_key, list);
343 sst_vconf_map = _map_erase(sst_vconf_map, iface->vconf_key);
348 return SYSTEM_SETTINGS_ERROR_NONE;