Added multi-callback for system-settings keys 82/159882/25 accepted/tizen/unified/20171206.063118 submit/tizen/20171205.083241
authorjinwang.an <jinwang.an@samsung.com>
Mon, 13 Nov 2017 11:30:10 +0000 (20:30 +0900)
committerjinwang.an <jinwang.an@samsung.com>
Tue, 5 Dec 2017 08:23:45 +0000 (17:23 +0900)
Change-Id: Ifee650239e79f02d1b3b38db276dbf253910a56d
Signed-off-by: jinwang.an <jinwang.an@samsung.com>
CMakeLists.txt
include/system_settings.h
include/system_settings_multi_callback.h [new file with mode: 0644]
include/system_settings_private.h
packaging/capi-system-system-settings.spec
src/system_setting_platform.c
src/system_setting_unittest.c
src/system_settings.c
src/system_settings_multi_callback.c [new file with mode: 0644]
src/system_settings_vconf.c

index 92c2bda..5c5d7fe 100755 (executable)
@@ -97,6 +97,7 @@ SET(SOURCES "src/system_setting_platform.c"
                        "src/system_settings.c"
                        "src/system_settings_json.c"
                        "src/system_settings_ringtones.c"
+                       "src/system_settings_multi_callback.c"
                        "src/system_settings_vconf.c")
 
 #SET(UNITSOURES "system_setting_unittest.c")
@@ -162,10 +163,10 @@ IF(UNIX)
 
 ADD_CUSTOM_TARGET (distclean @echo cleaning for source distribution)
 ADD_CUSTOM_COMMAND(
-        DEPENDS clean 
+        DEPENDS clean
         COMMENT "distribution clean"
         COMMAND find
-        ARGS    . 
+        ARGS    .
         -not -name config.cmake -and \(
         -name tester.c -or
         -name Testing -or
index 86b0fe9..26795e6 100644 (file)
@@ -346,6 +346,43 @@ int system_settings_add_value_string(system_settings_key_e key, const char *valu
  */
 int system_settings_delete_value_string(system_settings_key_e key, const char *value);
 
+
+/**
+ * @brief Adds a change event callback for the given system settings key.
+ * @details The difference between this function and system_settings_set_changed_cb() is that system_settings_set_changed_cb() can set only one callback for a given key, while system_settings_add_changed_cb() can set multiple callbacks for a given key.
+ * @since_tizen 5.0
+ * @remarks The @a key cannot be #SYSTEM_SETTINGS_KEY_DEFAULT_FONT_TYPE. When the feature related to the @a key is not supported on the device, #SYSTEM_SETTINGS_ERROR_NOT_SUPPORTED will be returned.
+
+ * @param[in] key The key name of the system settings
+ * @param[in] callback The callback function to invoke
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return     0 on success, otherwise a negative error value
+ * @retval     #SYSTEM_SETTINGS_ERROR_NONE Successful
+ * @retval     #SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval     #SYSTEM_SETTINGS_ERROR_NOT_SUPPORTED The related feature is not supported on the device
+ * @post system_settings_changed_cb() will be invoked.
+ *
+ * @see system_settings_remove_changed_cb()
+ * @see system_settings_changed_cb()
+ *
+*/
+int system_settings_add_changed_cb(system_settings_key_e key, system_settings_changed_cb callback, void *user_data);
+
+/**
+ * @brief Removes a change event callback function.
+ * @details The difference between this function and system_settings_unset_changed_cb() is that system_settings_unset_changed_cb() unsets the callback set with system_settings_set_changed_cb(), while system_settings_remove_changed_cb() removes callbacks added with system_settings_add_changed_cb()
+ * @since_tizen 5.0
+ * @remarks The @a key cannot be #SYSTEM_SETTINGS_KEY_DEFAULT_FONT_TYPE. When the feature related to the @a key is not supported on the device, #SYSTEM_SETTINGS_ERROR_NOT_SUPPORTED will be returned.
+ * @param[in] key The key name of the system settings
+ * @param[in] callback The callback function to be removed
+ * @return     0 on success, otherwise a negative error value
+ * @retval     #SYSTEM_SETTINGS_ERROR_NONE Successful
+ * @retval     #SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval     #SYSTEM_SETTINGS_ERROR_NOT_SUPPORTED The related feature is not supported on the device
+ *
+ * @see system_settings_add_changed_cb()
+ */
+int system_settings_remove_changed_cb(system_settings_key_e key, system_settings_changed_cb callback);
 /**
  * @}
  */
diff --git a/include/system_settings_multi_callback.h b/include/system_settings_multi_callback.h
new file mode 100644 (file)
index 0000000..1c352d6
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef __TIZEN_SYSTEM_SETTING_MULTI_CALLBACK_H__
+#define __TIZEN_SYSTEM_SETTING_MULTI_CALLBACK_H__
+#include <system_settings.h>
+#include <system-setting-config.h>
+#include <glib.h>
+
+typedef struct __st_multi_callback_node_
+{
+       system_settings_changed_cb callback;
+       void* user_data;
+}callback_node;
+
+typedef struct __st_multi_callback_list_
+{
+       GList * list;
+       int is_registered;
+}callback_list;
+
+int add_multi_callback(callback_list *handle, system_settings_changed_cb ptr, void* user_data);
+int delete_multi_callback(callback_list *handle, system_settings_changed_cb ptr);
+int invoke_callback_list(callback_list *handle, system_settings_key_e key);
+
+
+#endif /* __TIZEN_SYSTEM_SETTING_MULTI_CALLBACK_H__ */
index 569d838..eb4ca68 100644 (file)
@@ -25,6 +25,7 @@ extern "C"
 
 #include <dlog.h>
 #include <system_settings.h>
+#include <system_settings_multi_callback.h>
 
 #ifdef LOG_TAG
 #undef LOG_TAG
@@ -174,6 +175,8 @@ typedef struct {
 
        system_setting_feature_check_cb feature_check_cb;
 
+       callback_list changed_cb_list;
+
        void *user_data;                                                                                                /* user_data */
 
 } system_setting_s;
@@ -304,6 +307,42 @@ int system_setting_vconf_unset_changed_cb(const char *vconf_key, int slot);
 
 /**
  * @internal
+ * @brief Unset the system settings notification callback
+ * @since_tizen 4.0
+ * @param[in] key system_settings_key_e value to get vconf string
+ * @param[out] key_string string pointer to be assigned vconf string
+ * @return     0 on success, otherwise a negative error value
+ * @retval     #SYSTEM_SETTINGS_ERROR_NONE Successful
+ * @retval     #SYSTEM_SETTINGS_ERROR_NOT_SUPPORTED Not support system-settings API
+ */
+int system_settings_vconf_get_key_string(system_settings_key_e key, char **key_string);
+
+
+/**
+ * @internal
+ * @brief Unset the system settings notification callback
+ * @since_tizen 4.0
+ * @param[in] vconf_key vconf key name used in the code
+ * @param[in] key system_settings_key_e value.
+ * @return     0 on success, otherwise a negative error value
+ * @retval     #SYSTEM_SETTINGS_ERROR_NONE Successful
+ * @retval     #SYSTEM_SETTINGS_ERROR_IO_ERROR Internal I/O error
+ */
+int system_setting_vconf_set_changed_multi_cb(const char *vconf_key, system_settings_key_e key);
+
+/**
+ * @internal
+ * @brief Unset the system settings notification callback
+ * @since_tizen 4.0
+ * @param[in] vconf_key vconf key name used in the code
+ * @return     0 on success, otherwise a negative error value
+ * @retval     #SYSTEM_SETTINGS_ERROR_NONE Successful
+ * @retval     #SYSTEM_SETTINGS_ERROR_IO_ERROR Internal I/O error
+ */
+int system_setting_vconf_unset_changed_multi_cb(const char *vconf_key);
+
+/**
+ * @internal
  * @brief get current font size
  * @since_tizen 2.3
  * @param[in] key key name should be SYSTEM_SETTINGS_KEY_FONT_SIZE
index e4e5cc8..e089e9d 100755 (executable)
@@ -52,7 +52,7 @@ System setting api for get,set configuration
 %prep
 %setup -q
 
-%define tizen_profile_name mobile 
+%define tizen_profile_name mobile
 
 %build
 
@@ -137,6 +137,7 @@ make %{?jobs:-j%jobs}
 /usr/src/packages/BUILD/%{name}-%{version}/CMakeFiles/%{name}.dir/src/system_settings_json.c.gcno
 /usr/src/packages/BUILD/%{name}-%{version}/CMakeFiles/%{name}.dir/src/system_settings_ringtones.c.gcno
 /usr/src/packages/BUILD/%{name}-%{version}/CMakeFiles/%{name}.dir/src/system_settings_vconf.c.gcno
+/usr/src/packages/BUILD/%{name}-%{version}/CMakeFiles/%{name}.dir/src/system_settings_multi_callback.c.gcno
 /usr/src/packages/BUILD/%{name}-%{version}/system-settings-util/CMakeFiles/system-settings-util.dir/src/system_settings_util.c.gcno
 %endif
 %license LICENSE
index 2c87518..2c7ea35 100644 (file)
@@ -85,16 +85,6 @@ static int dl_is_available_font(char *str);
 static void dl_font_size_set();
 static void dl_font_config_set_notification();
 
-
-#ifndef VCONFKEY_SETAPPL_UDSM
-#define VCONFKEY_SETAPPL_UDSM "db/setting/udsm"
-#endif
-
-#ifndef VCONFKEY_SETAPPL_UDSM_PKGID_LIST
-#define VCONFKEY_SETAPPL_UDSM_PKGID_LIST "db/setting/udsm/pkgid_list"
-#endif
-
-
 /**
  * VCONFKEY_SETAPPL_CALL_RINGTONE_PATH_STR has a path of the ringtone file which user choose
  * @return the ringtone file path specified by user in normal case
index 214882c..5d13512 100644 (file)
@@ -1,5 +1,4 @@
 #include <glib.h>
-
 #include <Elementary.h>
 
 extern void unittest_platform();
index a1a35b0..3ac3efb 100644 (file)
@@ -16,8 +16,6 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
-
 #include <vconf.h>
 #include <dlog.h>
 
@@ -25,7 +23,6 @@
 #include <system_settings_private.h>
 
 #include <glib.h>
-#include <assert.h>
 
 #ifdef LOG_TAG
 #undef LOG_TAG
@@ -51,6 +48,7 @@ system_setting_s system_setting_table[] = {
                system_setting_del_incoming_call_ringtone,      /* DEL */
                system_setting_list_incoming_call_ringtone,     /* LIST */
                system_setting_feature_check_incoming_call,             /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
 
@@ -66,6 +64,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                system_setting_feature_check_home_screen,               /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
 
@@ -81,6 +80,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                system_setting_feature_check_lock_screen,               /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
 
@@ -96,6 +96,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
 
@@ -111,6 +112,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
 
@@ -126,6 +128,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
 
@@ -141,6 +144,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                system_setting_feature_check_notification_email,                /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -155,6 +159,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -169,6 +174,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -183,6 +189,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                system_setting_feature_check_lock_screen,               /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -197,6 +204,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -211,6 +219,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -225,6 +234,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -239,6 +249,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -253,6 +264,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -267,6 +279,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -281,6 +294,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -295,6 +309,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -309,6 +324,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -323,6 +339,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -337,6 +354,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -351,6 +369,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                system_setting_feature_check_incoming_call,             /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -365,6 +384,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -379,6 +399,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -393,6 +414,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -407,6 +429,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -421,6 +444,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                system_setting_feature_check_wifi,              /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -435,6 +459,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* del */
                NULL,           /* list */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -449,6 +474,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* del */
                NULL,           /* list */
                system_setting_feature_check_telephony,         /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
 
@@ -464,6 +490,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* del */
                NULL,           /* list */
                system_setting_feature_check_telephony,         /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -478,6 +505,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* del */
                NULL,           /* list */
                system_setting_feature_check_telephony,         /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -492,6 +520,7 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
@@ -506,10 +535,11 @@ system_setting_s system_setting_table[] = {
                NULL,           /* DEL */
                NULL,           /* LIST */
                NULL,           /* feature check */
+               { NULL, 0 }, /* changed callabck list */
                NULL,           /* user data */
        },
        {
-               SYSTEM_SETTINGS_MAX, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+               SYSTEM_SETTINGS_MAX, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, { NULL, 0 }, NULL
        }
 };
 
@@ -956,6 +986,84 @@ int system_settings_unset_changed_cb(system_settings_key_e key)
        return system_setting_unset_changed_cb(key);
 }
 
+int system_settings_add_changed_cb(system_settings_key_e key, system_settings_changed_cb callback, void *user_data)
+{
+       LOGE("Enter [%s]", __FUNCTION__);
+       char *vconf_string = NULL;
+       system_setting_h system_setting_item;
+
+       if (callback == NULL) {
+               return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (key == SYSTEM_SETTINGS_KEY_DEFAULT_FONT_TYPE)
+               return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
+
+       int ret = system_settings_get_item(key, &system_setting_item);
+       if (ret != 0) {
+               if (ret == SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER)
+                       LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid key", __FUNCTION__, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
+               return ret;
+       }
+
+       system_settings_vconf_get_key_string(key, &vconf_string);
+
+       /* Store the callback function from application side */
+       ret = add_multi_callback(&system_setting_item->changed_cb_list, callback, user_data);
+       if (ret != SYSTEM_SETTINGS_ERROR_NONE) {
+               LOGE("[%s] IO_ERROR(0x%08x) : failed to add muti-callback for the system settings", __FUNCTION__, ret);
+               return ret;
+       }
+
+       if (!system_setting_item->changed_cb_list.is_registered) {
+               int ret = system_setting_vconf_set_changed_multi_cb(vconf_string, key);
+               if (ret == SYSTEM_SETTINGS_ERROR_NONE)
+                       system_setting_item->changed_cb_list.is_registered = 1;
+               LOGE("Leave [%s]", __FUNCTION__);
+               return ret;
+       }
+
+       LOGE("Leave [%s]", __FUNCTION__);
+       return SYSTEM_SETTINGS_ERROR_NONE;
+}
+
+int system_settings_remove_changed_cb(system_settings_key_e key, system_settings_changed_cb callback)
+{
+       LOGE("Enter [%s]", __FUNCTION__);
+       char *vconf_string = NULL;
+       system_setting_h system_setting_item;
+
+       if (callback == NULL)
+               return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
+
+       if (key == SYSTEM_SETTINGS_KEY_DEFAULT_FONT_TYPE)
+               return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
+
+       int ret = system_settings_get_item(key, &system_setting_item);
+       if (ret != 0) {
+               if (ret == SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER)
+                       LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid key", __FUNCTION__, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
+               return ret;
+       }
+
+       delete_multi_callback(&system_setting_item->changed_cb_list, callback);
+
+       if (system_setting_item->changed_cb_list.list == NULL) {
+               int ret = 0;
+               system_settings_vconf_get_key_string(key, &vconf_string);
+               if (vconf_string == NULL)
+                       return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
+               ret = system_setting_vconf_unset_changed_multi_cb(vconf_string);
+               if (ret == SYSTEM_SETTINGS_ERROR_NONE)
+                       system_setting_item->changed_cb_list.is_registered = 0;
+               LOGE("Leave [%s]", __FUNCTION__);
+               return ret;
+       }
+
+       LOGE("Leave [%s]", __FUNCTION__);
+       return SYSTEM_SETTINGS_ERROR_NONE;
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////////////
 // list
 //////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1014,7 +1122,7 @@ static int my_assert_ret(int retcode)
        return 1;
 }
 
-static GMainLoop* main_loop = NULL;
+static GMainLoop* multi_main_loop = NULL;
 static bool _callback_called = false;
 //static char *new_ringtonepath = "/usr/apps/org.tizen.setting/shared/res/settings/Ringtones/Basic_Bell.ogg";
 static char *new_ringtonepath = "/opt/usr/data/settings/Ringtones/ringtone_sdk.mp3";
@@ -1054,7 +1162,6 @@ static void utc_system_settings_changed_callback(system_settings_key_e key, void
        /*g_main_loop_quit(main_loop);*/
 }
 
-
 /**
  * TEST GETTING SYSTEM_SETTINGS_KEY_DEFAULT_FONT_TYPE
  */
@@ -3178,6 +3285,75 @@ static void utc_system_settings_delete_ringtone_list_p1(void)
        return;
 }
 
+#include <unistd.h> /* to use sleep */
+static int call_cnt = 0;
+static void utc_system_settings_changed_multi_callback1(system_settings_key_e key, void *user_data)
+{
+       call_cnt++;
+}
+
+static void utc_system_settings_changed_multi_callback2(system_settings_key_e key, void *user_data)
+{
+       call_cnt++;
+       sleep(1);
+       g_main_loop_quit(multi_main_loop);
+}
+
+static void *test_multi_callback_thread(void *arg)
+{
+       int retcode = system_settings_add_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_TIMEFORMAT_24HOUR,
+                                                                                                utc_system_settings_changed_multi_callback1, NULL);
+       my_assert_ret(retcode);
+
+       retcode = system_settings_add_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_TIMEFORMAT_24HOUR,
+                                                                                                utc_system_settings_changed_multi_callback1, NULL);
+
+       /* not support same callback about 1 system-settings key */
+       g_assert_cmpint(retcode, ==, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
+
+       retcode = system_settings_add_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_TIMEFORMAT_24HOUR,
+                                                                                                utc_system_settings_changed_multi_callback2, NULL);
+
+       bool bk_state = false;
+       system_settings_get_value_bool(SYSTEM_SETTINGS_KEY_LOCALE_TIMEFORMAT_24HOUR , &bk_state);
+
+       bool state = true;
+       system_settings_set_value_bool(SYSTEM_SETTINGS_KEY_LOCALE_TIMEFORMAT_24HOUR , state);
+
+       sleep(1);
+
+       my_assert_ret(retcode);
+       retcode = system_settings_remove_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_TIMEFORMAT_24HOUR,
+                                                                                                utc_system_settings_changed_multi_callback1);
+       my_assert_ret(retcode);
+       retcode = system_settings_remove_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_TIMEFORMAT_24HOUR,
+                                                                                                utc_system_settings_changed_multi_callback2);
+       my_assert_ret(retcode);
+
+       system_settings_set_value_bool(SYSTEM_SETTINGS_KEY_LOCALE_TIMEFORMAT_24HOUR , bk_state);
+
+
+}
+/**
+ * @testcase           utc_system_settings_add_changed_cb_p1
+ * @since_tizen                4.0
+ * @description     check if SYSTEM_SETTINGS_KEY_LOCALE_TIMEFORMAT_24HOUR is able to set the callback for change-notification.
+ */
+static void utc_system_settings_add_changed_cb_p1(void)
+{
+       multi_main_loop = g_main_loop_new(NULL, FALSE);
+       pthread_t test_thread;
+
+       pthread_create(&test_thread, NULL, test_multi_callback_thread, NULL);
+       pthread_detach(test_thread);
+
+       g_main_loop_run(multi_main_loop);
+
+       g_assert_cmpint(call_cnt, ==, 2);
+       return;
+}
+
+
 static void simple_test_case(void)
 {
        /* a suitable test */
@@ -3191,6 +3367,7 @@ void unittest_api()
 {
        /* hook up your test functions */
        g_test_add_func("/API Test Case", simple_test_case);
+       g_test_add_func("/utc_system_settings_add_changed_cb_p1", utc_system_settings_add_changed_cb_p1);
        g_test_add_func("/utc_system_settings_get_value_string_p1", utc_system_settings_get_value_string_p1);
        g_test_add_func("/utc_system_settings_get_value_string_p2", utc_system_settings_get_value_string_p2);
        g_test_add_func("/utc_system_settings_get_value_string_p3", utc_system_settings_get_value_string_p3);
diff --git a/src/system_settings_multi_callback.c b/src/system_settings_multi_callback.c
new file mode 100644 (file)
index 0000000..13dcf09
--- /dev/null
@@ -0,0 +1,115 @@
+#include <stdlib.h>
+#include <system_settings_private.h>
+
+void clean_node(callback_node* node)
+{
+       if (!node)
+               return;
+
+       node->callback = NULL;
+       node->user_data = NULL;
+}
+
+
+callback_node* alloc_multi_callback_node()
+{
+       callback_node* node = NULL;
+       node = (callback_node*)malloc(sizeof(callback_node));
+
+       if (node == NULL) {
+               SETTING_TRACE("Not enough node....");
+               return NULL;
+       }
+
+       clean_node(node);
+
+       return node;
+}
+
+void free_multi_callback_node(callback_node* node)
+{
+       if (node)
+               free(node);
+       return;
+}
+
+GList* find_callback_node(callback_list *handle, system_settings_changed_cb ptr)
+{
+       if (!handle)
+               return NULL;
+
+       GList * list = handle->list;
+
+       GList * itr = g_list_first(handle->list);
+       while (itr != NULL) {
+               callback_node* node = (callback_node*)itr->data;
+               if (node->callback == ptr)
+                       return itr;
+               itr = g_list_next(itr);
+       }
+
+       return itr; /* itr == NULL NOT found! */
+}
+
+
+int delete_multi_callback(callback_list *handle, system_settings_changed_cb ptr)
+{
+       SETTING_TRACE_BEGIN;
+       if (!handle || !ptr)
+               return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
+
+       GList* itr = find_callback_node(handle, ptr);
+       if (itr) {
+               g_list_remove_link(handle->list, itr);
+               free_multi_callback_node((callback_node*)itr->data);
+               g_list_free(itr);
+       }
+
+       SETTING_TRACE_END;
+       return SYSTEM_SETTINGS_ERROR_NONE;
+}
+
+int add_multi_callback(callback_list *handle, system_settings_changed_cb ptr, void *user_data)
+{
+       SETTING_TRACE_BEGIN;
+       if (!handle || !ptr)
+               return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
+
+       GList* itr = find_callback_node(handle, ptr);
+       if (itr != NULL)
+               return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
+
+       callback_node* node = alloc_multi_callback_node();
+
+       if (node == NULL)
+               return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
+
+       node->callback = ptr;
+       node->user_data = user_data;
+
+       /* append the node to list. free_multi_callback_node will free the node */
+       handle->list = g_list_append(handle->list, node);
+
+       SETTING_TRACE_END;
+       return SYSTEM_SETTINGS_ERROR_NONE;
+}
+
+int invoke_callback_list(callback_list *handle, system_settings_key_e key)
+{
+       SETTING_TRACE_BEGIN;
+       if (!handle)
+               return SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER;
+
+       GList * list = handle->list;
+
+       GList * itr = g_list_first(handle->list);
+       while (itr != NULL) {
+               callback_node* node = (callback_node*)itr->data;
+               if (node->callback)
+                       node->callback(key, node->user_data);
+               itr = g_list_next(itr);
+       }
+
+       SETTING_TRACE_END;
+       return SYSTEM_SETTINGS_ERROR_NONE;
+}
index 3c9e778..f736ab1 100644 (file)
 
 #define LOG_TAG "TIZEN_N_SYSTEM_SETTINGS"
 
+static char* _system_settings_vconf_table[38] = {
+       VCONFKEY_SETAPPL_CALL_RINGTONE_PATH_STR,
+       VCONFKEY_BGSET,
+       VCONFKEY_IDLE_LOCK_BGSET,
+       VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE,
+       VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME,
+       VCONFKEY_SETAPPL_MOTION_ACTIVATION,
+       VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR,
+       VCONFKEY_SETAPPL_USB_DEBUG_MODE_BOOL,
+       VCONFKEY_3G_ENABLE,
+       NULL,
+       VCONFKEY_SETAPPL_3RD_LOCK_PKG_NAME_STR,
+       NULL,
+       VCONFKEY_REGIONFORMAT,
+       VCONFKEY_LANGSET,
+       VCONFKEY_REGIONFORMAT_TIME1224,
+       VCONFKEY_SETAPPL_TIMEZONE_ID,
+       VCONFKEY_SYSTEM_TIME_CHANGED,
+       VCONFKEY_SETAPPL_SOUND_LOCK_BOOL,
+       VCONFKEY_SETAPPL_SOUND_STATUS_BOOL,
+       VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL,
+       VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
+       VCONFKEY_SETAPPL_DEVICE_NAME_STR,
+       VCONFKEY_SETAPPL_MOTION_ACTIVATION,
+       VCONFKEY_WIFI_ENABLE_QS,
+       VCONFKEY_TELEPHONY_FLIGHT_MODE,
+       VCONFKEY_SETAPPL_LCD_TIMEOUT_NORMAL,
+       VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR,
+       VCONFKEY_SETAPPL_NOTI_MSG_ALERT_REP_TYPE_INT,
+       VCONFKEY_IDLE_LOCK_STATE_READ_ONLY,
+       VCONFKEY_SETAPPL_AD_ID,
+       VCONFKEY_SETAPPL_UDSM,
+       VCONFKEY_SETAPPL_UDSM_PKGID_LIST,
+       VCONFKEY_SETAPPL_ACCESSIBILITY_TTS,
+       VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL,
+       "MAX"
+};
 
 int system_setting_vconf_get_value_int(const char *vconf_key, int *value)
 {
@@ -273,4 +310,61 @@ int system_setting_vconf_unset_changed_cb(const char *vconf_key, int slot)
        return SYSTEM_SETTINGS_ERROR_NONE;
 }
 
+int system_settings_vconf_get_key_string(system_settings_key_e key, char **key_string)
+{
+       if (key == SYSTEM_SETTINGS_KEY_DEFAULT_FONT_TYPE) {
+               *key_string = NULL; /* Not Supported changed callback*/
+               return SYSTEM_SETTINGS_ERROR_NOT_SUPPORTED;
+       }
+
+       *key_string = _system_settings_vconf_table[(int)key];
+
+       if (*key_string == NULL)
+               return SYSTEM_SETTINGS_ERROR_NOT_SUPPORTED;
+
+       return SYSTEM_SETTINGS_ERROR_NONE;
+}
+
+static void system_setting_vconf_event_multi_cb(keynode_t *node, void *event_data)
+{
+       LOGE("Enter [%s]", __FUNCTION__);
+       system_settings_key_e pkey = (system_settings_key_e)event_data;
+
+       if (node != NULL) {
+               system_setting_h system_setting_item;
+
+               int ret = system_settings_get_item(pkey, &system_setting_item);
+               if (ret != 0) {
+                       if (ret == SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER)
+                               LOGE("[%s] INVALID_PARAMETER(0x%08x) : invalid key", __FUNCTION__, SYSTEM_SETTINGS_ERROR_INVALID_PARAMETER);
+               }
+
+               invoke_callback_list(&system_setting_item->changed_cb_list, pkey);
+       }
+       LOGE("Leave [%s]", __FUNCTION__);
+}
+
+int system_setting_vconf_set_changed_multi_cb(const char *vconf_key, system_settings_key_e key)
+{
+       LOGE("Enter [%s]", __FUNCTION__);
+       if (vconf_notify_key_changed(vconf_key, system_setting_vconf_event_multi_cb, (void *)key)) {
+               LOGE("[%s] INVALID_error , %s", __FUNCTION__, "vconf_notify_key_changed error");
+               return SYSTEM_SETTINGS_ERROR_IO_ERROR;
+       }
+
+       LOGE("Leave [%s]", __FUNCTION__);
+       return SYSTEM_SETTINGS_ERROR_NONE;
+}
+
+int system_setting_vconf_unset_changed_multi_cb(const char *vconf_key)
+{
+       LOGE("Enter [%s]", __FUNCTION__);
+       if (vconf_ignore_key_changed(vconf_key, system_setting_vconf_event_multi_cb)) {
+               LOGE("[%s] INVALID_error , %s", __FUNCTION__, "vconf_ignore_key_changed error");
+               return SYSTEM_SETTINGS_ERROR_IO_ERROR;
+       }
+
+       LOGE("Leave [%s]", __FUNCTION__);
+       return SYSTEM_SETTINGS_ERROR_NONE;
+}