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_old = NULL;
29 static GHashTable *sst_vconf_map = NULL;
30 static GHashTable *sst_vconf_map_new = NULL;
32 struct sst_vconf_info_s {
33 system_settings_key_e key;
34 system_settings_changed_cb cb;
38 int sst_vconf_set_int(sst_interface *iface, int val)
40 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
41 RETV_IF(NULL == iface->vconf_key, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
43 if (VCONF_OK != vconf_set_int(iface->vconf_key, val)) {
44 ERR("vconf_set_int(%s, %d) Fail", iface->vconf_key, val);
45 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
48 return SYSTEM_SETTINGS_ERROR_NONE;
51 int sst_vconf_set_bool(sst_interface *iface, bool val)
53 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
54 RETV_IF(NULL == iface->vconf_key, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
56 if (VCONF_OK != vconf_set_bool(iface->vconf_key, val)) {
57 ERR("vconf_set_bool(%s, %d) Fail", iface->vconf_key, val);
58 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
61 return SYSTEM_SETTINGS_ERROR_NONE;
64 int sst_vconf_set_str(sst_interface *iface, const char *val)
66 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
67 RETV_IF(NULL == iface->vconf_key, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
69 if (VCONF_OK != vconf_set_str(iface->vconf_key, val)) {
70 ERR("vconf_set_str(%s, %s) Fail", iface->vconf_key, val);
71 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
74 return SYSTEM_SETTINGS_ERROR_NONE;
77 int sst_vconf_get_int(sst_interface *iface, int *val)
79 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
80 RETV_IF(NULL == iface->vconf_key, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
83 if (VCONF_OK != vconf_get_int(iface->vconf_key, &result)) {
84 ERR("vconf_get_int(%s) Fail", iface->vconf_key);
85 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
90 return SYSTEM_SETTINGS_ERROR_NONE;
93 int sst_vconf_get_bool(sst_interface *iface, bool *val)
95 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
96 RETV_IF(NULL == iface->vconf_key, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
99 if (VCONF_OK != vconf_get_bool(iface->vconf_key, &result)) {
100 ERR("vconf_get_bool(%s) Fail", iface->vconf_key);
101 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
104 *val = result ? true : false;
106 return SYSTEM_SETTINGS_ERROR_NONE;
109 int sst_vconf_get_str(sst_interface *iface, char **val)
111 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
112 RETV_IF(NULL == iface->vconf_key, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
114 char *result = vconf_get_str(iface->vconf_key);
115 if (NULL == result) {
116 ERR("vconf_get_str(%s) Fail(NULL)", iface->vconf_key);
117 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
121 return SYSTEM_SETTINGS_ERROR_NONE;
124 int sst_vconf_get_str_ally(const char *vconf_key, char **value)
126 char *str_value = vconf_get_str(vconf_key);
127 if (NULL == str_value) {
128 ERR("vconf_get_str(%s) Fail(NULL)", vconf_key);
129 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
133 return SYSTEM_SETTINGS_ERROR_NONE;
136 //Because of a lot of parameters, it is an inline function
137 static inline int _subscribe(sst_interface *iface, system_settings_changed_cb cb, void *user_data, GHashTable **vconf_map, GList *list, vconf_callback_fn vconf_cb, system_settings_cb_id *id)
139 GHashTable *map = *vconf_map;
140 struct sst_vconf_info_s *info = malloc(sizeof(struct sst_vconf_info_s));
142 ERR("malloc() Fail(%d)", errno);
143 return SYSTEM_SETTINGS_ERROR_OUT_OF_MEMORY;
145 info->key = iface->key;
147 info->cb_data = user_data;
149 GList *new_list = g_list_append(list, info);
150 g_hash_table_replace(map, (char*)iface->vconf_key, new_list);
153 int ret = vconf_notify_key_changed(iface->vconf_key, vconf_cb, NULL);
154 if (VCONF_OK != ret) {
155 ERR("vconf_notify_key_changed(%s) Fail", iface->vconf_key);
156 new_list = g_list_remove(new_list, info);
157 if (NULL == new_list) {
158 g_hash_table_remove(map, iface->vconf_key);
159 if (0 == g_hash_table_size(map)) {
160 g_hash_table_unref(map);
165 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
172 return SYSTEM_SETTINGS_ERROR_NONE;
175 static int _unsubscribe(const char *vconf_key, GList *found, GHashTable **vconf_map, vconf_callback_fn cb)
177 GHashTable *map = *vconf_map;
178 GList *list = g_list_first(found);
180 if (1 == g_list_length(list)) {
181 int ret = vconf_ignore_key_changed(vconf_key, cb);
182 if (VCONF_OK != ret) {
183 ERR("vconf_ignore_key_changed(%s) Fail", vconf_key);
184 return SYSTEM_SETTINGS_ERROR_IO_ERROR;
188 list = g_list_remove_link(list, found);
190 g_hash_table_replace(map, (char*)vconf_key, list);
192 g_hash_table_remove(map, vconf_key);
193 if (0 == g_hash_table_size(map)) {
194 g_hash_table_unref(map);
202 return SYSTEM_SETTINGS_ERROR_NONE;
205 static void _callback_fn_old(keynode_t *node, void *user_data)
207 RET_IF(NULL == sst_vconf_map_old);
209 GList *list = g_hash_table_lookup(sst_vconf_map_old, node->keyname);
211 for (it = list; it; it = it->next) {
212 struct sst_vconf_info_s *info = it->data;
213 if (info && info->cb)
214 info->cb(info->key, info->cb_data);
218 static gint _compare_key(gconstpointer a, gconstpointer b)
220 const struct sst_vconf_info_s *info = a;
222 RETV_IF(NULL == a, 1);
224 if (info->key == GPOINTER_TO_INT(b))
230 int sst_vconf_set_cb(sst_interface *iface, system_settings_changed_cb cb, void *user_data)
234 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
235 RETV_IF(NULL == cb, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
237 if (sst_vconf_map_old) {
238 list = g_hash_table_lookup(sst_vconf_map_old, iface->vconf_key);
239 GList *found = g_list_find_custom(list, GINT_TO_POINTER(iface->key), _compare_key);
241 ERR("callback Already Exist");
242 return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
245 sst_vconf_map_old = g_hash_table_new(g_str_hash, g_str_equal);
248 return _subscribe(iface, cb, user_data, &sst_vconf_map_old, list, _callback_fn_old, NULL);
251 int sst_vconf_unset_cb(sst_interface *iface)
253 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
254 RETV_IF(NULL == sst_vconf_map_old, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
256 GList *list = g_hash_table_lookup(sst_vconf_map_old, iface->vconf_key);
257 GList *found = g_list_find_custom(list, GINT_TO_POINTER(iface->key), _compare_key);
260 return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
263 return _unsubscribe(iface->vconf_key, found, &sst_vconf_map_old, _callback_fn_old);
266 static void _callback_fn(keynode_t *node, void *user_data)
268 RET_IF(NULL == sst_vconf_map);
270 GList *list = g_hash_table_lookup(sst_vconf_map, node->keyname);
272 for (it = list; it; it = it->next) {
273 struct sst_vconf_info_s *info = it->data;
274 if (info && info->cb)
275 info->cb(info->key, info->cb_data);
279 static gint _compare_cb(gconstpointer a, gconstpointer b)
281 const struct sst_vconf_info_s *info = a;
283 RETV_IF(NULL == a, 1);
284 RETV_IF(NULL == b, 1);
292 int sst_vconf_add_multi_cb(sst_interface *iface, system_settings_changed_cb cb, void *user_data)
296 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
297 RETV_IF(NULL == cb, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
300 list = g_hash_table_lookup(sst_vconf_map, iface->vconf_key);
301 GList *found = g_list_find_custom(list, cb, _compare_cb);
303 ERR("callback Already Exist");
304 return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
307 sst_vconf_map = g_hash_table_new(g_str_hash, g_str_equal);
310 return _subscribe(iface, cb, user_data, &sst_vconf_map, list, _callback_fn, NULL);
313 int sst_vconf_del_multi_cb(sst_interface *iface, system_settings_changed_cb cb)
315 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
316 RETV_IF(NULL == cb, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
317 RETV_IF(NULL == sst_vconf_map, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
319 GList *list = g_hash_table_lookup(sst_vconf_map, iface->vconf_key);
320 GList *found = g_list_find_custom(list, cb, _compare_cb);
323 return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
326 return _unsubscribe(iface->vconf_key, found, &sst_vconf_map, _callback_fn);
329 static void _callback_fn_new(keynode_t *node, void *user_data)
331 RET_IF(NULL == sst_vconf_map_new);
333 GList *list = g_hash_table_lookup(sst_vconf_map_new, node->keyname);
335 for (it = list; it; it = it->next) {
336 struct sst_vconf_info_s *info = it->data;
337 if (info && info->cb)
338 info->cb(info->key, info->cb_data);
342 int sst_vconf_subscribe(sst_interface *iface, system_settings_changed_cb cb, void *user_data, system_settings_cb_id *id)
346 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
347 RETV_IF(NULL == cb, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
349 if (sst_vconf_map_new) {
350 list = g_hash_table_lookup(sst_vconf_map_new, iface->vconf_key);
352 sst_vconf_map_new = g_hash_table_new(g_str_hash, g_str_equal);
355 return _subscribe(iface, cb, user_data, &sst_vconf_map_new, list, _callback_fn_new, id);
358 int sst_vconf_unsubscribe(sst_interface *iface, system_settings_cb_id id)
360 RETV_IF(NULL == iface, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
361 RETV_IF(NULL == id, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
362 RETV_IF(NULL == sst_vconf_map_new, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
364 GList *list = g_hash_table_lookup(sst_vconf_map_new, iface->vconf_key);
365 GList *found = g_list_find(list, id);
368 return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
371 return _unsubscribe(iface->vconf_key, found, &sst_vconf_map_new, _callback_fn_new);